admin管理员组文章数量:1323029
I have this Javascript constructor-
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();
Gives me this error -
Uncaught TypeError: Object [object global] has no method 'fooBar'
I tried console.log
and found out that when I call this.start
from within setInterval
, this
points to the window
object. Why is this so?
I have this Javascript constructor-
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();
Gives me this error -
Uncaught TypeError: Object [object global] has no method 'fooBar'
I tried console.log
and found out that when I call this.start
from within setInterval
, this
points to the window
object. Why is this so?
-
1
setInterval
iswindow.setInterval
sothis
refers towindow
– kidwon Commented Mar 19, 2013 at 11:49 - 1 @kidwon - That's not the reason. See my answer below for the correct reason: stackoverflow./a/15587589/783743 – Aadit M Shah Commented Mar 23, 2013 at 14:05
3 Answers
Reset to default 5The this
pointer can point to one of many things depending upon the context:
- In constructor functions (function calls preceded by
new
)this
points to the newly created instance of the constructor. - When a function is called as a method of an object (e.g.
obj.funct()
) then thethis
pointer inside the function points to the object. - You can explicitly set what
this
points to by usingcall
,apply
orbind
. - If none of the above then the
this
pointer points to the global object by default. In browsers this is thewindow
object.
In your case you're calling this.start
inside setInterval
. Now consider this dummy implementation of setInterval
:
function setInterval(funct, delay) {
// native code
}
It's important to understand that start
is not being called as this.start
. It's being called as funct
. It's like doing something like this:
var funct = this.start;
funct();
Now both these functions would normally execute the same, but there's one tiny problem - the this
pointer points to the global object in the second case while it points to the current this
in the first.
An important distinction to make is that we're talking about the this
pointer inside start
. Consider:
this.start(); // this inside start points to this
var funct = this.start;
funct(); // this inside funct (start) point to window
This is not a bug. This is the way JavaScript works. When you call a function as a method of an object (see my second point above) the this
pointer inside the function points to that object.
In the second case since funct
is not being called as a method of an object the fourth rule is applied by default. Hence this
points to window
.
You can solve this problem by binding start
to the current this
pointer and then passing it to setInterval
as follows:
setInterval(this.start.bind(this), 200);
That's it. Hope this explanation helped you understand a little bit more about the awesomeness of JavaScript.
Here is a neat way to do OOP with javascript:
//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();
This way you encapsulate your methods and variables into a namespace/class to make it much easier use and maintain.
Therefore you could write your code like this:
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);
Initially, the ID is set to 'Foo' After 1 second the ID is set to 'bar'
Notice all variables and methods are encapsulated inside the TestEngine class.
Try this:
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
calls start
function with window context. It means when start
gets executed, this
inside start
function points to window
object. And window object don't have any method called fooBar
& you get the error.
Anonymous function approach:
It is a good practice to pass anonymous function
to setInterval
and call your function from it. This will be useful if your function makes use of this
.
What I did is, created a temp variable self
& assigned this
to it when it is pointing your TestEngine instance & calling self.start()
function with it.
Now inside start
function, this
will be pointing to your testInstance & everything will work as expected.
Bind approach:
Bind
will make your life easier & also increase readability of your code.
TestEngine.prototype.startMethod = function() {
setInterval(this.start.bind(this), 200);
}
本文标签: javascriptUnable to access the object using this this points to window objectStack Overflow
版权声明:本文标题:javascript - Unable to access the object using `this`. `this` points to `window` object - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742109877a2421195.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论