Object this and setTimeout

T

Telmo Costa

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?
 
T

Thomas 'PointedEars' Lahn

tihu wrote:

[included minimum quotation]

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
 
T

Telmo Costa

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
 
T

Thomas 'PointedEars' Lahn

Telmo said:
Thanks. I think I got it.

You're welcome. Please also learn to quote properly.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top