Object this and setTimeout

Discussion in 'Javascript' started by Telmo Costa, Feb 21, 2006.

  1. Telmo Costa

    Telmo Costa Guest

    I have a HTML page with a form with 2 buttons like this

    ....
    <input type="button" value="Add" onClick="ClickAdd();"/>
    <input type="button" value="Reset" onClick="ClickReset();"/>
    ....

    I also have this javascript code:

    ----------------------------------------

    function ClickAdd() {
    setTimeout(test.Add, 100);
    //test.Add();
    };

    function ClickReset() {
    setTimeout(test.Add, 100);
    //test.Reset();
    };

    Test = function () {
    this.total = 0;
    };

    Test.prototype.Add = function() {
    this.total++;
    alert(this);
    };

    Test.prototype.Reset = function(i) {
    this.total = 0;
    alert(this);
    };

    Test.prototype.toString = function() {
    return (this.total);
    };

    test = new Test();

    -------------------------------------------


    the thing is:

    in the ClickAdd function, if i call test.Add() directly, is works ok
    But if I call it using setTimeout, the /alert(this)/ shows
    [object Window]

    Why? And what should i do to make it work as i want?
    Telmo Costa, Feb 21, 2006
    #1
    1. Advertising

  2. tihu wrote:

    [included minimum quotation]

    > Telmo Costa wrote:
    > > Test = function () {
    > > this.total = 0;
    > > }


    Telmo, you should declare your identifiers; variables with the `var'
    keyword. Furthermore, there is no need for a FunctionExpression here,
    a FunctionDeclaration suffices for the constructor definition:

    function Test()
    {
    this.total = 0;
    }

    > > [...]
    > >
    > > test = new Test();

    >
    > [...]
    > Because window.setTimeout uses "test.Add" only as a function ( rather
    > than a function which is a method of a Test object )


    Only loosely speaking, and that it is _window_.setTimeout() does not matter
    regarding this. All functions are methods; globally available functions
    are methods of the Global Object (ECMAScript 3 Final, section 15). If only
    the Function object `test.Add' refers to is [[Call]]ed, that object is
    called as a method of the Global Object because the base object component
    of the Reference value is the Global Object, no longer `test' (13.2.1).
    Therefore, the `this' value, which refers to the caller (or the object that
    is [[Construct]]ed, see section 10.1.7), refers to the Global Object in the
    code of the called Function object.

    > then the object found by 'this' is the window object.


    No, it is the Global Object augmented with host-defined properties.
    Its `window' property is one of those property and refers to to the
    Global Object itself in many, if not all, HTML document object models.

    > To get your script to work add an extra argument to the add and reset
    > prototypes then change the arguments in the setTimeout call:
    >
    >
    > Test.prototype.Add = function( thisObj ) {
    > thisObj.total++;
    > alert(thisObj);
    > };
    >
    > Test.prototype.Reset = function(thisObj) {
    > thisObj.total = 0;
    > alert(thisObj);
    > };
    >
    > function ClickAdd() {
    > setTimeout(test.Add, 100, test );
    > };
    >
    > function ClickReset() {
    > setTimeout(test.Reset, 100, test);
    > };
    >
    > It aint pretty but it seems to work ok


    Every implementation that supports a Function object reference as first
    argument of window.setTimeout() also supports FunctionExpressions.

    window.setTimeout(function() { test.Reset() }, 100);

    There is no need to modify the signature of either method of the Test
    prototype object. That said, there is no need to use a function reference
    here at all because `test' is globally available (but should be declared a
    variable anyway):

    window.setTimeout("test.Reset()", 100);

    (I recommend against using identifiers starting with capital letter for
    functions, unless they are intended to be a constructor or factory.)

    Please quote the minimum of what you are referring to:

    <URL:http://jibbering.com/faq/faq_notes/pots1.html#ps1Post>
    <URL:http://safalra.com/special/googlegroupsreply/>


    PointedEars
    Thomas 'PointedEars' Lahn, Feb 22, 2006
    #2
    1. Advertising

  3. Telmo Costa

    Telmo Costa Guest

    Thanks. I think I got it.

    >
    > Telmo, you should declare your identifiers; variables with the `var'
    > keyword. Furthermore, there is no need for a FunctionExpression here,
    > a FunctionDeclaration suffices for the constructor definition:
    >

    ....
    > (I recommend against using identifiers starting with capital letter for
    > functions, unless they are intended to be a constructor or factory.)
    >


    So, for a base function/object i should go with FunctionDeclaration:

    function test() {
    ...
    }

    var t = new test();

    (is it just a recommendation, or is there something more?)

    But, for an inner function it should go with the FunctionExpression:

    var test.innerTest = function() {
    ...
    };


    innerTest is now a static method of the static global method test.
    furthermore, it can be instatiated this way:

    var inner = new test.innerTest();


    right?

    telmo
    Telmo Costa, Feb 22, 2006
    #3
  4. Telmo Costa wrote:

    > Thanks. I think I got it.


    You're welcome. Please also learn to quote properly.

    >> Telmo, you should declare your identifiers; variables with the `var'
    >> keyword. Furthermore, there is no need for a FunctionExpression here,
    >> a FunctionDeclaration suffices for the constructor definition:

    > ...
    >> (I recommend against using identifiers starting with capital letter for
    >> functions, unless they are intended to be a constructor or factory.)

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > So, for a base function/object i should go with FunctionDeclaration:
    >
    > function test() {
    > ...
    > }


    No, test() /is/ your constructor:

    > var t = new test();

    ^^^^^^^^

    Therefore:

    function Test()
    {
    ...
    }

    > (is it just a recommendation, or is there something more?)


    There is no syntax rule. But you will observe that all host objects
    follow that convention. It avoids confusion, one way or the other.

    > But, for an inner function it should go with the FunctionExpression:
    >
    > var test.innerTest = function() {
    > ...
    > };


    No, I said you should declare _identifiers_. `test.innerText' is none,
    it is a property access. Therefore, the above is a syntax error.

    test.innerTest = function() {
    ...
    };

    is just fine. What do you mean by "inner function" anyway?

    > innerTest is now a static method of the static global method test.


    No, it is not. Furthermore there are no static methods in ECMAScript
    implementations in HTML user agents.

    > furthermore, it can be instatiated this way:
    >
    > var inner = new test.innerTest();
    >
    >
    > right?


    No, see above. And "instantiated", if this class-based term can even be
    applied to this prototype-based language, is the object referred to with
    `inner', where `test.innerTest' is its constructor (and a reference to it
    can be obtained with `inner.constructor' then.)


    HTH

    PointedEars
    Thomas 'PointedEars' Lahn, Feb 22, 2006
    #4
    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. Andy Pickering

    Smart navigation and js setTimeout

    Andy Pickering, Oct 24, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    486
    Andy Pickering
    Oct 27, 2003
  2. Ken
    Replies:
    4
    Views:
    105
    Michael Winter
    Oct 7, 2004
  3. Andrew Poulos

    setTimeout and an object's methods

    Andrew Poulos, Mar 5, 2006, in forum: Javascript
    Replies:
    12
    Views:
    220
    Dr John Stockton
    Mar 13, 2006
  4. Replies:
    2
    Views:
    70
  5. -Lost
    Replies:
    7
    Views:
    171
    -Lost
    Mar 24, 2007
Loading...

Share This Page