Darko wrote:
I have this particular problem with eval() when using
Microsoft Internet Explorer, when trying to define an
event handler. This is the code:
function BigObject()
{
this.items = new Array();
this.values = new Array();
this.addItem = function( item )
{
this.items[this.items.leng th] = item;
}
This - addItem - method does not take advantage of its status as an inner
function (its unique identify and the closure resulting form its
assignment). Under those circumstances it would be better to assign it to
the - BigObject.proto ype - so a single function object may be shared as
an instance method of all - BigObject - instances.
this.makeHandle rs()
Noting the correction; this.makeHandle rs = function()
{
var i, length = this.items.leng th;
for ( i = 0; i < length; i++ )
this.items[i].onclick = function()
{ alert( this.values[i] ); };
In javascript the value of the - this - keyword is determined by how a
function is called. It is not a property of the function objects
themselves. In response to events, a browser calls the functions assigned
to its intrinsic event properties as methods of the DOM Element to which
the handler is assigned, this leaves the - this - keyword referring to
the DOM Element.
}
This method makes no use of its status as an inner function and so should
again be assigned to the prototype.
}
However, this last code (makeHandlers() method) doesn't work
since the expression "this.value s[i]" automatically belongs
to this new anonymous function,
No, it doesn't work because - this - refers to the DOM Element and the -
i - value belongs to the one containing execution and has the value it
had when the - for - loop finished.
and therefore isn't valid (since the new anonymous
function(s) don't have the "values" attribute.
They don't, but it is the DOM Element not having a - values - property
that is significant here.
So I tried the following:
this.items[i].onclick = eval( "function() { alert( " +
this.values[i] + "); }" );
and it worked!
It would be more accurate to say that where it 'worked' it actually
failed to fail as expected. The - eval - function executes its string
argument as a complete javascript Program, and the units that a Program
can be made up of are Statements and FunctionDeclara tions. A
FunctionDeclara tion must have an Identifier as the function name, so your
string is not a syntactically correct FunctionDeclara tion. A statement
may not start with the - function - keyword, so your string is not a
syntactically correct Statement, and so it also cannot be a syntactically
correct javascript Program.
A combination of using - eval - (which often acts to mask errors, or make
them indirect/obscure) , syntax extensions and error tolerance
(particularly in IE's case) may conspire to give the impression of
something that 'works', but there is nothing in the language to suggest
that this would ever be effective code to be writing.
... in Firefox only :( Internet explorer returns
"undefined" for eval( "function() { /* whatever */ ); } " ),
for the same things Firefox perfectly understands, and if I
try to make it a handler, an exception is fired in IE.
You are not allowed to assign the undefined value to an intrinsic event
property in IE.
What do I do?
<snip>
First, learning javascript's syntax might be of some use while attempting
to write it.
You need to have a function that is called as a method of a DOM element
reference a property of a particular javascript object instance, and
employ an individual and unique index with that property. The following
will do that, but you will have to look at the URL reference to
understand why:-
function BigObject(){
this.items = new Array();
this.values = new Array();
}
BigObject.proto type.addItem = function(item){
this.items[this.items.leng th] = item;
};
BigObject.proto type.makeHandle rs = function(){
var i, length = this.items.leng th;
var self = this; // Make the object instance available on the scope
// chain as a - self - variable.
for ( i = 0; i < length; i++ ){
this.items[i].onclick = (function(index ){
return (function(){
alert( self.values[index] ); // self - is resolved
// against the scope
// chain, and resolves as
// a reference to the
// individual javascript
// object instance
// assigned in the
// outermost function with
// the - this - keyword.
});
})(i); // Pass the individual index - i - as an argument to the
// function call that returns the event handling
// function. This allows the event handling function to
// reference its index as the outer unction's - index -
// formal parameter.
}
};
See:-
<URL:
http://jibbering.com/faq/faq_notes/closures.html >
Richard.