无法使用“this”访问对象.“this”指向“窗口”对象
Unable to access the object using `this`. `this` points to `window` object
我有这个Javascript构造函数-
function TestEngine() {
this.id='Foo';
}
TestEngine.prototype.fooBar = function() {
this.id='bar';
return true;
}
TestEngine.prototype.start = function() {
this.fooBar();
}
TestEngine.prototype.startMethod = function() {
inter = setInterval(this.start, 200);
}
var test = new TestEngine();
test.startMethod();
给了我这个错误——
Uncaught TypeError: Object [object global] has no method 'fooBar'
我尝试了console.log
,发现当我从setInterval
内部调用this.start
时,this
指向window
对象。为什么会这样?
this
指针可以指向许多事物之一,具体取决于上下文:
- 在构造函数(函数调用前面有
new
(中,this
指向新创建的构造函数实例。 - 当函数作为对象的方法调用时(例如
obj.funct()
(,则函数内的this
指针指向该对象。 - 您可以使用
call
、apply
或bind
显式设置this
指向的内容。 - 如果以上都不是,则默认情况下
this
指针指向全局对象。在浏览器中,这是window
对象。
在您的情况下,您正在setInterval
内部呼叫this.start
。现在考虑这个setInterval
的虚拟实现:
function setInterval(funct, delay) {
// native code
}
重要的是要了解start
不被称为this.start
。它被称为funct
。就像做这样的事情:
var funct = this.start;
funct();
现在这两个函数通常执行相同的操作,但有一个小问题 - 在第二种情况下,this
指针指向全局对象,而在第一种情况下指向当前this
。
要做出的一个重要区别是,我们谈论的是 start
内部的this
指针。考虑:
this.start(); // this inside start points to this
var funct = this.start;
funct(); // this inside funct (start) point to window
这不是错误。这就是 JavaScript 的工作方式。当你调用一个函数作为一个对象的方法时(参见我上面的第二点(,函数内的this
指针指向该对象。
在第二种情况下,由于funct
不是作为对象的方法调用的,因此默认情况下应用第四条规则。因此,this
指向window
.
可以通过将start
绑定到当前this
指针,然后将其传递给setInterval
来解决此问题,如下所示:
setInterval(this.start.bind(this), 200);
就是这样。希望这个解释能帮助你更多地了解JavaScript的伟大之处。
以下是使用 javascript 执行 OOP 的巧妙方法:
//Global Namespace:
var MyNamespace = MyNamespace || {};
//Classes:
MyNamespace.MyObject = function () {
this.PublicVar = 'public'; //Public variable
var _privatVar = 'private'; //Private variable
//Public methods:
this.PublicMethod = function () {
}
//Private methods:
function PrivateMethod() {
}
}
//USAGE EXAMPLE:
var myObj = new MyNamespace.MyObject();
myObj.PublicMethod();
通过这种方式,您可以将方法和变量封装到命名空间/类中,使其更易于使用和维护。
因此,您可以像这样编写代码:
var MyNamespace = MyNamespace || {};
//Class: TestEngine
MyNamespace.TestEngine = function () {
this.ID = null;
var _inter = null;
//Public methods:
this.StartMethod = function (id) {
this.ID = id;
_inter = setInterval(Start, 1000);
}
//Private methods:
function Start() {
FooBar();
console.log(this.ID);
}
function FooBar() {
this.ID = 'bar';
return true;
}
}
//USAGE EXAMPLE:
var testEngine = new MyNamespace.TestEngine();
testEngine.StartMethod('Foo');
console.log(testEngine.ID);
最初,ID 设置为"Foo"1 秒后,ID 设置为"bar"
请注意,所有变量和方法都封装在 TestEngine 类中。
试试这个:
function TestEngine() {
this.id='Foo';
}
TestEngine.prototype.fooBar = function() {
this.id='bar';
return true;
}
TestEngine.prototype.start = function() {
this.fooBar();
}
TestEngine.prototype.startMethod = function() {
var self = this;
var inter = setInterval(function() {
self.start();
}, 200);
}
var test = new TestEngine();
test.startMethod();
setInterval
调用start
具有窗口上下文的函数。这意味着当start
被执行时,start
函数内部this
指向window
对象。窗口对象没有任何称为fooBar
的方法,你得到错误。
匿名函数方法:
最好将anonymous function
传递给setInterval
并从中调用函数。如果您的函数使用 this
,这将很有用。
我所做的是,创建一个临时变量self
并在它指向您的 TestEngine 实例并使用它调用self.start()
函数时为其分配this
。
现在start
函数中,this
将指向您的testInstance,一切都将按预期工作。
绑定方法:
Bind
将使您的生活更轻松,并提高代码的可读性。
TestEngine.prototype.startMethod = function() {
setInterval(this.start.bind(this), 200);
}
- javascript中对象构造函数中的var属性与this.properties
- 定义this.properties或objectName.properties的javascript JSON对象
- 如何使用(this)访问Angular 2 http rxjs catch函数中的对象属性
- Javascript 对象和 this 关键字
- jquery$(this)对象缺少问题
- Javascript对象来获取父方法的this
- 如何绑定“;这个“;在$http.post中->在AngularJS中解析/拒绝?(现在this=Window对象
- 将“this”关键字发送到对象中
- jQuery双对象构造函数-例如$($(this))
- ui.selectmenu投掷'this.newelement.0'为null或不是对象
- 警告 - 全局 THIS 对象的危险使用
- $.each 中的“this”,当需要使用“this”访问对象的函数时
- Javascript对象文字,如何使用“this”来引用对象中的变量
- 为什么当我尝试将函数绑定到自身时,“this”对象仍然引用窗口
- TypeScript:在对象文字字段中的访问器中访问外部“this”
- 在将对象传递给数组时,在 this.x 上给“x”一个变量值
- 将对象this发送到不带参数的函数
- 使用HTML5音频和jQuery对调用对象(this)的引用
- Javascript在对象中使用绑定,我如何访问对象this
- 无法使用“this”访问对象.“this”指向“窗口”对象