setTimeout within the context of an Object loses context.

Discussion in 'Javascript' started by -Lost, Mar 23, 2007.

  1. -Lost

    -Lost Guest

    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
     
    -Lost, Mar 23, 2007
    #1
    1. Advertising

  2. -Lost

    Danny Guest

    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
    -Lost wrote:

    > 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
     
    Danny, Mar 23, 2007
    #2
    1. Advertising

  3. -Lost

    -Lost Guest

    > -Lost wrote:
    >
    >> 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" <> wrote in message
    news:JlKMh.686$...
    > 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
     
    -Lost, Mar 23, 2007
    #3
  4. -Lost

    -Lost Guest

    "-Lost" <> wrote in message
    news:...
    >> -Lost wrote:


    >> 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."


    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
     
    -Lost, Mar 23, 2007
    #4
  5. On Mar 23, 1:29 am, "-Lost" <> wrote:
    > > -Lost wrote:

    >
    > >> 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:

    >


    >
    > > 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."



    use

    setTimeout(function(){alert(this)},1000)
     
    scripts.contact, Mar 23, 2007
    #5
  6. -Lost

    RobG Guest

    On Mar 23, 4:00 pm, "-Lost" <> wrote:
    > 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.


    --
    Rob
     
    RobG, Mar 23, 2007
    #6
  7. -Lost

    RobG Guest

    On Mar 23, 4:21 pm, Danny <> wrote:
    > 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);


    --
    Rob
     
    RobG, Mar 23, 2007
    #7
  8. -Lost

    -Lost Guest

    "RobG" <> wrote in message
    news:...
    > On Mar 23, 4:00 pm, "-Lost" <> wrote:
    >> 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
     
    -Lost, Mar 24, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    297
  2. Ken
    Replies:
    4
    Views:
    131
    Michael Winter
    Oct 7, 2004
  3. cisono
    Replies:
    10
    Views:
    194
    A. Sinan Unur
    Aug 27, 2005
  4. Telmo Costa

    Object this and setTimeout

    Telmo Costa, Feb 21, 2006, in forum: Javascript
    Replies:
    3
    Views:
    103
    Thomas 'PointedEars' Lahn
    Feb 22, 2006
  5. Replies:
    10
    Views:
    257
    Ian Kelly
    Dec 20, 2012
Loading...

Share This Page