I tested the following code in IE6, IE7 and IE8 with the same result:
<a name="cd"/>a</a> <script> try { cd = new Date; } catch(e) { alert(e); } </script>
In all cases an error is thrown. However using
var cd = new Date;
seems to solve the problem.
Does a开发者_C百科nyone know why that is ?Here is an example: http://jsbin.com/ahuhu4/2
When you don't use the var specifier to declare your variable, the variable cd is added as a property to the window object, e.g. window.cd
. You already have an object element that is a child of window that is <a name="cd">a</a>
which is already typed. You can't specify new Date as a type for this object as it already exists. When you use the var keyword, you are rescoping the variable to a local scope and removing its direct attachment to the window object. This removes the error and allows IE to proceed. Other browser engines handle this differently.
IE does you the great favor of creating properties of window
for each page element with an "id" value. It's just a thing. (note: this statement is not really true.)
edit — yes, the element doesn't have "id". OK, well good news - IE also treats references by name as if they were by "id". Recall that document.getElementById("cd")
on that page would return a reference to the <a>
, just as it would if it had an "id" element.
edit again I think it's not quite correct to say that IE creates actualy window
properties, at least by my reading of what the IE8 debugger is telling me. It's more like the interpreter treats an implicit reference to a global variable ("cd" in this case) as a request for it to go look for something in the global page context by that name. To IE, that process includes checking the DOM for elements with that "id" or "name" value. By using the var
keyword, you're explicitly telling the interpreter that you're declaring a symbol in the applicable scope (global, here), so that "lookup" process is skipped.
// Firefox does not automatically define global variables for elements with ids or names. IE including #9, Opera 10, Safari 5 and Chrome 6 all do maintain a global rollcall of named or id'd elements in the document.
It seems like it could crowd up the global namespace...
function a1(id){
try{
window[id].style.color= 'red';
}
catch(er){
return er.message+'\n'+'window.'+id+' = '+window[id];
}
return 'window.'+id+'='+window[id];
}
function a2(id){
window[id]= 'red';
return 'window.'+id+'='+window[id]
}
/*
firefox returns window[idstring] is undefined.
The others all find it, just like the old IE document.all object.
- query the id as a global identifier:
alert(a1('idstring'))
colors the element red and returns[object HTMLButtonElement]
(returns [object Object] in older ie browsers)
assign the global a new value: alert(a2('idstring')) returns 'red'
Try the element again alert(a1('idstring'))
throws an error - Cannot convert 'window[id].style' to object
- or Cannot set property 'color' of undefined or
- Result of expression 'window[id].style' [undefined] is not an object ot
- Object expected
*/
精彩评论