In the code below, when somethingUseful.thisUsefulThing
is called from setTimeout
, can it reference somethingUseful.thatUsefulThing
?
var somethingUseful = {
thisUsefulThing: function() {
this.thatUsefulThing();
},
thatUsefulThing: function() {
console.log("I am useful!");
}
}
setTimeout(somethingUseful.thisUsefulThing, 1000);
Right now, I am getting this error:
Uncaught TypeError: Object [object global] has no method 'thatUsefulThing'
In the code below, when somethingUseful.thisUsefulThing
is called from setTimeout
, can it reference somethingUseful.thatUsefulThing
?
var somethingUseful = {
thisUsefulThing: function() {
this.thatUsefulThing();
},
thatUsefulThing: function() {
console.log("I am useful!");
}
}
setTimeout(somethingUseful.thisUsefulThing, 1000);
Right now, I am getting this error:
Uncaught TypeError: Object [object global] has no method 'thatUsefulThing'
Share
Improve this question
edited Oct 23, 2013 at 23:38
Synthead
asked Oct 23, 2013 at 23:20
SyntheadSynthead
2,3215 gold badges24 silver badges26 bronze badges
6
- 6 What do you mean "scope of global" vs "scope of the object"? Your code as written works. – user2736012 Commented Oct 23, 2013 at 23:22
-
1
Just keep in mind that when you do
object.method()
, the value ofthis
inmethod
bees a reference toobject
. Makes no difference where or when the object and method were created. All that matters is how you call the method. Put that same method on a different object, call it from that object, and the value ofthis
will refer to the new object.var o = {thatUsefulThing:function() {console.log("I'm useful too!");}}; o.foo = somethingUseful.thisUsefulThing; o.foo(); // I'm useful too
– user2736012 Commented Oct 23, 2013 at 23:32 - There, I edited it to directly reflect the error I'm encountering in a nutshell. – Synthead Commented Oct 23, 2013 at 23:38
-
That's because you're sending the method to
setTimeout
by detaching it from the object. Remember,this
is determined by how the method is called. When you doobject.method()
, themethod
can see that it is being called fromobject
sothis
beesobject
. If you detach it, as I showed in my ment above, itsthis
will be based on how it was now being called. If it's not called from some object, it gets the defaultwindow
object. – user2736012 Commented Oct 23, 2013 at 23:42 -
...to keep them joined, pass an anonymous function that invokes the method from the object.
setTimeout(function() {somethingUseful.thisUsefulThing();}, 1000);
– user2736012 Commented Oct 23, 2013 at 23:44
2 Answers
Reset to default 3To simply answer your question, YES, thisUsefulThing CAN access thatUsefulThing
But as your code currently runs, 'this' is not actually global, it is a reference to somethingUseful to all direct descendants itself.
When I am working with literal objects, I usually reference them by name rather than with 'this', so in your case I would replace 'this.thatUsefulThing()' with somethingUseful.thatUsefulThing()
Why? Because it works globally, anyway!
EDIT:
As plalx pointed out in his ment to my answer, best practices for implementing this class (with an example class member) would use functional classes / prototypes and look something like this:
function SomethingUseful () {
this.member = 'I am a member';
}
SomethingUseful.prototype.thisUsefulThing = function () {
this.thatUsefulThing();
}
SomethingUseful.prototype.thatUsefulThing = function () {
console.log('I am useful, and ' + this.member);
}
usefulObject = new SomethingUseful();
usefulObject.thisUsefulThing(); // logs fine with access to this.member
setInterval(usefulObject.thisUsefulThing.bind(usefulObject), 1000); // has access to this.member through bind()
Just bind the this
value to somethingUseful
.
setTimeout(somethingUseful.thisUsefulThing.bind(somethingUseful), 1000);