setTimeout and anonymous functions

F

Frank O'Hara

Hello everyone, I'm just learning some of the depth that Javascript
has to offer. I have to say that it is quite amazing. Anyway, I'm
translating some of my older, classical code to try to take advantage
of some of the new things I'm learning but I'm a little stuck with
this one (see snip):

<snip>
document.getElementById("button1").blink = function (duration)
{
var that = this;

var originalDisplay = that.getAttribute("display");
var newDipslay;

if (originalDisplay === undefined ||
originalDisplay == "")
{
originalDisplay = "inline";
newDisplay = "none";
}
else
{
originalDisplay = "none";
newDisplay = "inline";
}

that.setAttribute("display",newDisplay);
setTimeout(function ()
{that.setAttribute("display",originalDisplay);that=null;},duration);
// setTimeout(function () {alert('asdf');},duration);
};

document.getElementById("button1").blink(1000);
</snip>

This isn't working and I'm not 100% certain why not. The anonymous
function is not being called after 1000 msec (duration). I tried with
the easier, commented, line but that didn't execute either.

While I'm intrigued by the features that Javascript has to offer, I'm
finding it difficult to know when/why/where to use them. I'm sure
that will improve as I see it solve problems for me but for now I'm
feeling rather 'dumb'.

Any help would be appreciated.

Thanks,
Frank.
 
J

Jeremy

Frank said:
document.getElementById("button1").blink = function (duration)
{
var that = this;

//snipped
};

document.getElementById("button1").blink(1000);

What do you suppose "this" means in the context of this function? You
are assuming that it refers to the element of which the blink function
is a property, but such an assumption is not correct.

The function you assigned to the HTML element is simply being called as
a function; the element is never added to the scope as "this". You
could fix this by passing the element as another parameter to the
function, but this probably breaks the elegance that you were expecting
to get.

You will probably have to re-think the approach for doing this. Some
browsers will let you modify the prototype of HTMLElement (meaning you
could theoretically add a "blink" method that would be executed with
"this" in scope), but others (IE) do not (and doing so is probably a bad
idea).

There are other approaches which would let you accomplish similar
things, but the added complication is not (in my opinion) a worthwhile
payoff. Keep it simple; avoid relying on "this" when interacting with
the DOM until you are more experienced in what "this" really means in
different contexts.

Jeremy
 
F

Frank O'Hara

What do you suppose "this" means in the context of this function?  You
are assuming that it refers to the element of which the blink function
is a property, but such an assumption is not correct.

Jeremy, thanks for the post.

At first I assumed "this" was a reference to the actual "blink"
function and had planned on adding element as an arguement to the
function but it turns out that 'this' indeed was a reference to the
element, although admittedly I'm not 100% certain why. I guess in the
context of calling the function
(document.getElementById("button1").blink(1000);
) 'this' is a pointer to the element.

So, back to my original query which is how to make the execute an
anonymous function in setTimeout? Then if I can get that to work,
then I can worry about HOW to actually ensure that the correct object
is being passed to it. Right now the function is not executing.

Thanks,
Frank
 
G

gentsquash

Hello Frank O'Hara

I can't analyse the problem, but I can point out that in your posted
code
you have
var newDipslay;

and later
newDisplay = "inline";

Presumably you intended these to both refer to "newDisplay".

--gentsquash
 
F

Frank O'Hara

Hello Frank O'Hara

I can't analyse the problem, but I can point out that in your posted
code
you have


and later


Presumably you intended these to both refer to "newDisplay".

                                 --gentsquash

Thanks for catching that typo. Yes they should both be referring to
the same variable.

However, I have got it working - thanks to those who posted replies.
The problem was less one of my code (minus the typos) but rather the
fact that I'm not using it in a conventional Html application. The js
is residing in an SVG file which has a slightly different DOM. I'm
going to have to play with it more because taking it out of the SVG
environment and using it in a strictly Html file proved successful
(after modifying if for the differences in the DOM).

Thanks again,
Stephan
 
F

Frank O'Hara

Hello Frank O'Hara

I can't analyse the problem, but I can point out that in your posted
code
you have


and later


Presumably you intended these to both refer to "newDisplay".

                                 --gentsquash

Thanks for catching that typo. Yes they should both be referring to
the same variable.

However, I have got it working (sorta) - thank you to those who posted
replies.
The problem was less one of my code (minus the typos) but rather the
fact that I'm not using it in a conventional Html application. The
js
is residing in an SVG file which has a slightly different DOM. I'm
going to have to play with it more because taking it out of the SVG
environment and using it in a strictly Html file proved successful
(after modifying if for the differences in the DOM).


Thanks again,
Frank
 
R

Richard Cornford

Jeremy said:
What do you suppose "this" means in the context of this function?
You are assuming that it refers to the element of which the blink
function is a property, but such an assumption is not correct.

Javascript determines the - this - value based entirely upon how a
function is called, at the point of calling the function (applying a
specified algorithm and having a totally predictable outcome). We can
see the function call here and so be certain that the - this - value in
the called function will be the same object as referred to by -
document.getElementById("button1") -.
The function you assigned to the HTML element is simply being
called as a function;

In one sense all functions are call as functions, but here it would be
reasonable to say that the function is being called as a method of the -
document.getElementById("button1") - object.
the element is never added to the scope as "this".

Scope and - this - values are unrelated. Scope is determined lexically
from the structure of the source code (except where a - with -
statement adds something to the scope chain) while - this - values are
determined by how code is called.
You could fix this by passing the element as another parameter
to the function, but this probably breaks the elegance that you
were expecting to get.

But there is nothing to fix here.
You will probably have to re-think the approach for doing this.
Some browsers will let you modify the prototype of HTMLElement
(meaning you could theoretically add a "blink" method that
would be executed with "this" in scope),

Modifying the prototype (if possible) would make no difference to the
determination of the - this - value, it still depends on how the
function/method is called.
but others (IE) do not (and doing so is probably a bad idea).

There are other approaches which would let you accomplish
similar things, but the added complication is not (in my
opinion) a worthwhile payoff. Keep it simple; avoid relying
on "this" when interacting with the DOM until you are more
experienced in what "this" really means in different contexts.

Yes, knowing how the - this - value is determined probably would be of
assistance in determining how javascript code should be
written/designed.

Richard.
 
J

Jeremy

Richard said:
Javascript determines the - this - value based entirely upon how a
function is called, at the point of calling the function (applying a
specified algorithm and having a totally predictable outcome). We can
see the function call here and so be certain that the - this - value in
the called function will be the same object as referred to by -
document.getElementById("button1") -.


In one sense all functions are call as functions, but here it would be
reasonable to say that the function is being called as a method of the -
document.getElementById("button1") - object.

Interesting. I would not expect that to be the case. My experience has
led me to avoid using "this" in any method that is not specifically
associated with a prototype (and called on an object with that
prototype), or has not been 'bound' to an instance with apply(). Seems
I am the one who needs to become 'more experienced in what "this" really
means in different contexts.'

I will place my foot firmly in my mouth now; thanks for the tip.

Jeremy
 
T

Thomas 'PointedEars' Lahn

Frank said:
Hello everyone, I'm just learning some of the depth that Javascript
has to offer. I have to say that it is quite amazing. Anyway, I'm
translating some of my older, classical code to try to take advantage
of some of the new things I'm learning but I'm a little stuck with
this one (see snip):

<snip>
document.getElementById("button1").blink = function (duration)
[...]

This isn't working and I'm not 100% certain why not. The anonymous
function is not being called after 1000 msec (duration). I tried with
the easier, commented, line but that didn't execute either.

In addition to what was already said, I have to point out that your code
indicates you are trying to augment a host object which is always a very bad
idea.

Host objects, much in contrast to native objects, may implement their own
version of the internal [[Put]] method used to add properties to an object
or modify an existing property. Therefore, they do not need to support
their augmentation with properties, or the modification of their existing
properties, and the result of the assignment can be anything from "nothing
changes" to "runtime error". I think it was Lasse Reichstein Nielsen who
put it so unequivocally: With host objects, all bets are off.

Have I already mentioned that you *really* want to avoid trying to augment
host objects?


PointedEars
 
F

Frank O'Hara

Frank said:
Hello everyone, I'm just learning some of the depth that Javascript
has to offer.  I have to say that it is quite amazing.  Anyway, I'm
translating some of my older, classical code to try to take advantage
of some of the new things I'm learning but I'm a little stuck with
this one (see snip):
<snip>
    document.getElementById("button1").blink = function (duration)
[...]
This isn't working and I'm not 100% certain why not.  The anonymous
function is not being called after 1000 msec (duration).  I tried with
the easier, commented, line but that didn't execute either.

In addition to what was already said, I have to point out that your code
indicates you are trying to augment a host object which is always a very bad
idea.

Host objects, much in contrast to native objects, may implement their own
version of the internal [[Put]] method used to add properties to an object
or modify an existing property.  Therefore, they do not need to support
their augmentation with properties, or the modification of their existing
properties, and the result of the assignment can be anything from "nothing
changes" to "runtime error".  I think it was Lasse Reichstein Nielsen who
put it so unequivocally: With host objects, all bets are off.

Have I already mentioned that you *really* want to avoid trying to augment
host objects?

PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

Thanks for the advice. This problem is made more challenging by the
fact that I'm working with JS in an SVG document which apparently (as
I've learned - read: pulling out what little hair remains) doesn't
like to behave like a standard Html document.

This is making learning 'standard' JS methodology a lot more difficult
but still fun...for now.

Frank
 
T

Thomas 'PointedEars' Lahn

Frank said:
Frank said:
<snip>
document.getElementById("button1").blink = function (duration)
[...] This isn't working and I'm not 100% certain why not. The
anonymous function is not being called after 1000 msec (duration). I
tried with the easier, commented, line but that didn't execute
either.
[...] Host objects, much in contrast to native objects, may implement
their own version of the internal [[Put]] method used to add properties
to an object or modify an existing property. Therefore, they do not
need to support their augmentation with properties, or the modification
of their existing properties, and the result of the assignment can be
anything from "nothing changes" to "runtime error". I think it was
Lasse Reichstein Nielsen who put it so unequivocally: With host
objects, all bets are off. [...]

Thanks for the advice.

You are welcome.
This problem is made more challenging by the fact that I'm working with
JS in an SVG document which apparently (as I've learned - read: pulling
out what little hair remains) doesn't like to behave like a standard Html
document.

That much would seem to be obvious: an SVG DOM (e.g. [SVGDOM] based on
[DOMCore], not an HTML DOM (e.g. [DOM2HTML] based on [DOMCore]). However,
because of that it would be possible that the object already has a `blink'
property (but I recommend feature-testing this anyway).
This is making learning 'standard' JS methodology a lot more difficult
but still fun...for now.

ISTM developing for an SVG DOM or another non-HTML DOM is the best possible
exercise to see the difference between the ECMAScript Language
Specification, the ECMAScript implementation (e.g. JavaScript), and the APIs
that can be used through the latter (e.g. [SVGDOM]).

Please trim your quotes.


PointedEars
___________
[SVGDOM] http://www.w3.org/TR/SVG/svgdom.html
[DOMCore] http://www.w3.org/TR/DOM-Level-2-Core/
http://www.w3.org/TR/DOM-Level-3-Core/
[DOM2HTML] http://www.w3.org/TR/DOM-Level-2-HTML/
 

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

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top