setTimeout within the context of an Object loses context.

L

-Lost

I am calling setTimeout within the context of an object, and whilst this exists, it
refuses to be passed along to the function I call. For example:

$elemById('id').change = function()
{
// the function returns the object itself, 'this' exists
alert(this); // [object HTMLSelectElement]
setTimeout('alert(this);',1000); // [object Window]
}

So, obviously there is something going on that I have not yet learned to deal with.
First, I went with assigning the object (this) to a variable. When I call it, I get
"variable is not defined" making me think that more than just dereferencing (the
reference's scope changing) is going on.

So, what am I missing?

-Lost
 
D

Danny

Yes indeed the 'this' scope does change, since 'this' is always the evented
caller, or the caller object to which the event/call occurring defaults to.
setTimeout() is a built-in object of window, or window.setTimeout(), and within
this scope

window.setTimeout('alert(this);',1000); // [object Window]

will be corrrect :)

alert(this); // [object HTMLSelectElement] // at the scope of the anonymous
function, will address, the object to where such function object, 'change', is
a member of.

You can always use a local var, to keep it within the scope, kinda cheesy as
it's, _this=this; setTimeout('alert(_this);',1000);

or such


Danny
 
L

-Lost

-Lost said:
I am calling setTimeout within the context of an object, and whilst this
exists, it
refuses to be passed along to the function I call. For example:

$elemById('id').change = function()
{
// the function returns the object itself, 'this' exists
alert(this); // [object HTMLSelectElement]
setTimeout('alert(this);',1000); // [object Window]
}

So, obviously there is something going on that I have not yet learned to deal
with.
First, I went with assigning the object (this) to a variable. When I call it,
I get "variable is not defined" making me think that more than just
dereferencing (the reference's scope changing) is going on.

So, what am I missing?

Danny said:
Yes indeed the 'this' scope does change, since 'this' is always the evented
caller, or the caller object to which the event/call occurring defaults to.
setTimeout() is a built-in object of window, or window.setTimeout(), and within
this scope

window.setTimeout('alert(this);',1000); // [object Window]

Ah, OK, that makes sense.
will be corrrect :)

However, if you were implying that changing it to window.setTimeout() fixes it, it does
not.
alert(this); // [object HTMLSelectElement] // at the scope of the anonymous
function, will address, the object to where such function object, 'change', is
a member of.

I did not understand this at all.
You can always use a local var, to keep it within the scope, kinda cheesy as
it's, _this=this; setTimeout('alert(_this);',1000);

or such

I have tried assigning it to a variable (like I said) and I always get "variable is not
defined."

-Lost
 
L

-Lost

-Lost said:
I have tried assigning it to a variable (like I said) and I always get "variable is not
defined."

Hrmm... I declared the variable with the var keyword and it appears within the context of
this object scope, caused problems. It may have something to do with the library I am
using (as I know you can declare variables within an object scope as local).

-Lost
 
R

RobG

I am calling setTimeout within the context of an object, and whilst this exists, it
refuses to be passed along to the function I call. For example:

$elemById('id').change = function()
{
// the function returns the object itself, 'this' exists
alert(this); // [object HTMLSelectElement]
setTimeout('alert(this);',1000); // [object Window]
}

The string passed to setTimeout is essentially eval'd as global code
when the time is up, at that point you have an anonymous function
whose this keyword references the window object.

If you want to get the original function's this, you need to set a
local variable and create a closure back to it:

$elemById('id').change = function() {
alert(this);
var that = this;
setTimeout(function(){alert(that)}, 1000);
}

So, obviously there is something going on that I have not yet learned to deal with.
First, I went with assigning the object (this) to a variable.

You didn't do that, you passed the string 'this' to be eval'd when the
setTimeout runs.
[...]
So, what am I missing?

Read the following Richard Cornford article on closures, it covers
quite a bit on function instantiation that is relevant here:

<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

Ignore pretty much everything else that's been said in this thread.
 
R

RobG

Yes indeed the 'this' scope does change,

Yes what? Please don't top-post here, reply below trimmed quotes.
But anyway...

No, it doesn't. A function's this keyword is set by the calling
function, that's it.
since 'this' is always the evented
caller, or the caller object to which the event/call occurring defaults to.

No, it's not. It is set by the calling function and can be set to
whatever the calling function wants it to be - read up on call and
apply methods.


[...]
You can always use a local var, to keep it within the scope, kinda cheesy as
it's, _this=this; setTimeout('alert(_this);',1000);

Which creates _this as a global variable, not local. Some other
function may change what it references in the meantime. If you use:

var _this = this;
setTimeout('alert(_this);',1000);

it still won't work because you are passing a string to setTimeout, it
can't reference the local _this. What I think you meant to use is:

var _this = this;
setTimeout(function(){alert(_this);}, 1000);
 
L

-Lost

RobG said:
I am calling setTimeout within the context of an object, and whilst this exists, it
refuses to be passed along to the function I call. For example:

$elemById('id').change = function()
{
// the function returns the object itself, 'this' exists
alert(this); // [object HTMLSelectElement]
setTimeout('alert(this);',1000); // [object Window]
}

The string passed to setTimeout is essentially eval'd as global code
when the time is up, at that point you have an anonymous function
whose this keyword references the window object.

OK, now *that* really made sense.
If you want to get the original function's this, you need to set a
local variable and create a closure back to it:

$elemById('id').change = function() {
alert(this);
var that = this;
setTimeout(function(){alert(that)}, 1000);
}

So, obviously there is something going on that I have not yet learned to deal with.
First, I went with assigning the object (this) to a variable.

You didn't do that, you passed the string 'this' to be eval'd when the
setTimeout runs.
[...]
So, what am I missing?

Read the following Richard Cornford article on closures, it covers
quite a bit on function instantiation that is relevant here:

<URL: http://www.jibbering.com/faq/faq_notes/closures.html >

Ignore pretty much everything else that's been said in this thread.

Thanks, Rob. I will definitely read that article again!

Thanks for all the clarification as well.

-Lost
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top