Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > Object this and setTimeout

Reply
Thread Tools

Object this and setTimeout

 
 
Telmo Costa
Guest
Posts: n/a
 
      02-21-2006
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?



 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      02-22-2006
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
 
Reply With Quote
 
 
 
 
Telmo Costa
Guest
Posts: n/a
 
      02-22-2006

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

 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      02-22-2006
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
setTimeout within the context of an Object loses context. -Lost Javascript 7 03-24-2007 12:14 AM
setTimeout in object methods using closures (old problem?) rain_c1@web.de Javascript 2 05-22-2006 03:25 PM
setTimeout and an object's methods Andrew Poulos Javascript 12 03-13-2006 11:28 PM
Object creation - Do we really need to create a parent for a derieved object - can't the base object just point to an already created base object jon wayne C++ 9 09-22-2005 02:06 AM
Help with Passing an object to SetTimeOut function Ken Javascript 4 10-07-2004 11:29 AM



Advertisments