Adding events in a loop with arguments

T

Thomas 'PointedEars' Lahn

David said:
Well, if what you are implying were true, then code like this would
fail with an error:

if (document & document.getElementById && alert) { alert('test'); }

No, it would not. Apparently you have not even understood what the scope
chain is.


PointedEars
 
D

David Mark

David said:
[...]
if (this.document && this.document.getElementsByTagName && this.alert)
{
this.onload = function() {
Why set "global" then not use it above?
var l;
var ahrefs = global.document.getElementsByTagName("a");
It is used right there.
Which is below where I asked the question about the code above.
It was unclear to me what you were after. I posted a more detailed
explanation later.
l = ahrefs.length;
while (l--) {
ahrefs[l].href = '#';
ahrefs[l].tabIndex = 0;
ahrefs[l].onclick = (function(j) { return function()
{ global.alert(j); return false; }; })(l + 1);
And there.
Wherever possible, assigning a function expression that forms a
circular reference should be avoided else IE's famous memory leak
becomes an issue. This particular form effectively breaks the closure
with i, but creates an additional execution object on the scope chain
that exacerbates the leak.
This can be avoided by setting ahrefs to null at the end. It was an
oversight that I left this out.
It breaks the cirulcar reference (and hence a common cause of memory
leaks) but not the closure that each function expression assigned as
Of course it doesn't "break" the closure. I don't know what that
means and the closures are necessary for the example.

No, they aren't. In fact breaking the closure to i is what this thread
is all about. The closure with the outer function is a by-product of
the function expression assignment and is a bit of a nuisance here.


I don't see that at all. Closures are not inherently leaky. That is
a myth that was spread by Microsoft because they didn't understand why
their own code leaked.

The closure makes the circular reference possible, so it's good to not
create them if they aren't needed. That doesn't mean to say they are
inherently bad, just that the OP should be aware.

[...]
2. Assign the handler outside the scope of the main function like:
assignHandler(element, event, functionRef [, paramArray]);
Then you have to rely on Function.prototype.apply,
Not necessarily, the OP's example does not require it so "it's not an
issue in this case". :)
I don't know what you mean. Do you have an example of this
hypothetical assignHandler function that handles arguments (as the OP
requires) and does not use use call or apply?

I'm sure you can do it, but that you are currently thinking of a general
function that will handle every case. If there is no need to set the
handler's this keyword to the element, and if you know how many
arguments will be called, then something like the following suits (it
will only work in browsers that support addEventListener, but could
easily accommodate attachEvent also):

<div>
<button id="b0">Button 0</button>
<button id="b1">Button 1</button>
</div>
<script type="text/javascript">

function showArg(id, i){
alert('Button ' + id + ': ' + i);
}

function assignHandler(el, event, fn, arg0, arg1) {
if (el && el.addEventListener) {
el.addEventListener(event,
function(){fn(arg0, arg1)},
false);
}
el = null;

Looks like virtually the same thing to me, but with extra function
calls during initialization. Granted it limits the scope of the
closures, but it adds global functions.
}

(function() {
var button;
var buttons = document.getElementsByTagName('button');
for (var i=0, len=buttons.length; i<len; i++) {
button = buttons;
assignHandler(button, 'click', showArg, button.id, i);
}
button = null;
buttons = null;
})();

</script>

Now if that were to be a general function, it would need to consider
attachEvent and also probably use call or apply to both set the called
function's this keyword and to pass an unknown number of arguments.
Right.


But the OP's case doesn't require it, so such a general function isn't
necessary.




Those are the issues.
A function to do what?

I glanced at that briefly. Looks like a mess to me.

I think Mike would agree, his intention was to show that for the very
small number of browsers in use that require it, it can be done.


But certainly shouldn't be done.
3. Use the built-in Function object as a constructor:
ahrefs[1].onclick = new Function('...');
That is an alias for eval.
The use of eval is not necessarily evil, using the built-in Function
Obviously not. There are some rare cases where it is unavoidable and
appropriate.
All I am suggesting is that it would not be appropriate to use for
code like this example. It is too slow.

It may not be appropriate for many reasons, but I doubt that speed is
one of them.

I think that listeners of any substance will slow down the
initialization if they must be evaluated during assignment.
 
D

David Mark

No, it would not. Apparently you have not even understood what the scope
chain is.

Of course I understand what the scope chain is. And it isn't much of
a chain in this example. Since you insist that the global and window
objects can be different, then what do you think that implies about
the global scope? I know you have posted numerous times in the past
about it being "proprietary and error-prone" to assume that the window
object is the global object, whenever you see things like:

var foo = window['bar']; // bar is a globally declared variable

That's because in your mind, bar could be a property of something that
is not the window object (e.g. the global object.) It seems to me
that you are now contradicting yourself. Somebody correct me if I am
wrong (preferably somebody other than PointedEars.)
 
D

David Mark

a rumor - "a story or statement in general circulation without
confirmation or certainty as to facts"

Thanks for that.
Exactly what it is in relevance to Function constructor.



Think of "rumor" as explained above but with more stress on "not
true": though let's skip on this local vernacular expression, "a
rumor" will suffice.

That was really more of an exclamation than a question. As in, I was
surprised and slightly confused as to why you would describe
conceptions about the slowness of eval as an "ancient city legend."
Let me rephrase:

A what?!!
Once on executing the relevant assignment statement to be exact. It is
not what most people thinks though when opposing to Function(...)
usage - I am glad that you are not one of them.

I am glad you are glad (I think.) I am reserving judgment until I get
to the bottom of this post.
Runtime execution cache - what is also called JIT in Java - was
totally rebuilt and improved.

I would have to take your word on that. I don't think I want it.
Then you might explain it better. For me the advantages/disadvantages
from the productivity point of view are:

1) Slower on instantiation: so say assignment
var foo1 = function(m){window.alert(m);};
as always and noticeable quicker then
var foo2 = new Function('m', 'window.alert(m)');

That was my point all along and your "benchmark" didn't measure that.
2) Slower on invocation: so say
foo1('Hello!');
is always and noticeable quicker then
foo2('Hello!');

This is what your demo did measure and it was unrelated to my point
about Function constructors.
Neither of above are true so what is the 3rd issue you are concerned
about?

There is no 3rd issue. Your benchmark measured something that I
wasn't talking about and failed to measure anything that I was talking
about. This led me to believe that you did not understand the issue
at hand. It appears that you were at least aware of the issue, but
for some odd reason wrote a benchmark demo that didn't address it.
 
T

Thomas 'PointedEars' Lahn

David said:
David said:
[...] Thomas 'PointedEars' Lahn [...] wrote:
David Mark wrote:
[...] Thomas 'PointedEars' Lahn [...] wrote:
David Mark wrote:
In browsers the global window property refers to the global object
by convention,
Wrong.
I disagree. Can you give an example of one browser where it doesn't.
I have no intention of helping you to shift the burden of proof.
Well, if what you are implying were true, then code like this would
fail with an error:
if (document & document.getElementById && alert) { alert('test'); }
No, it would not. Apparently you have not even understood what the scope
chain is.

Of course I understand what the scope chain is. And it isn't much of
a chain in this example. Since you insist that the global and window
objects can be different, then what do you think that implies about
the global scope?

That there is an object in the scope chain of the corresponding execution
context that the host-defined `window' property of the Global Object refers
to. Nothing more, nothing less.


PointedEars
 
V

VK

It appears that you were at least aware of the issue, but
for some odd reason wrote a benchmark demo that didn't address it.

It is the same odd reason why many people were happy with unbalanced
Internet connection: a relatively weak but cheap upstream link and
more expensive quick downstream link. Now with the price drop it's
fading out, but the possibility itself of such offer was that 99% of
traffic is unbalanced: we are downloading 1000 or more times more than
uploading (unless some active p2p member). As the result we rarely
care of the upload speed but very sensitive for any download speed
drop.

Coming back to the issue: 99% of the existing programs are unbalanced
as well: instantiations are taking only small part of the process
lifetime (mostly at the beginning) and invocations of all kinds are
taking the rest. So yes, I was surprised that new Function call takes
times longer than function() assignment. It was a surprise because I
never cared how exactly long does it take - as long as the execution
on an average PC starts satisfactory quickly. I am always concerned
though of the runtime performance of the program itself: responsive
interface, smooth animation, no memory leaks and crashes on long run.
This is what I was testing, and if it takes extra ms per instantiation
at the beginning then I don't care. I am more scared of people - not
meaning anyone personally - who are using everywhere and despite
anything anonymous function() assignment "because it is faster" and
then adding extra DOM calls and null assignments to fight with
parasite closures they created themselves as if anything after var
foo=function(){} comes for 0 processor time.
 

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
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top