代码改变世界

【javascript基础】之【IE著名bug——如果某个实例属性与标为[[DontEnum]]的某个属性同名,那么该实例属性不会出现在for in】

2012-05-21 14:54  sniper007  阅读(1598)  评论(16编辑  收藏  举报

【题记】每次看《javascript高级程序设计》第九章第二节的“怪癖检测”的时候,看到IE的bug,看一下,知道有这么一个东西,因为实际项目中还没有用到这个,今天再看,势必要把这个搞清楚。

【正文】如果某个实例属性与标为[[DontEnum]]的某个属性同名,那么该实例属性不会出现在for in,

测试

 

<div id="txt"></div>
<script>
var arr = {
    
"first":1,
    
"second":2,
    
"third":3,
    toString : 
function(){},
    valueOf : 
function(){},
    constructor : 
11,
    hasOwnProperty : 
function(){},
    isPrototypeOf : 
function(){}
/*    propertyIsEnumerable : function(obj){
    }
*/
};
var txt = document.getElementById("txt");
var str = "";
for(var o in arr){
    str 
+= o + "'s [[DontEnum]] is " +  arr.propertyIsEnumerable(o) + "<br />" ;
}
txt.innerHTML 
= str;
</script>

结果如下,IE9,firefox,chrome,safari,opera都显示如下:

 

而IE8,6,7显示如下:

 

可见,IE9已经修复了这个bug, IE8以及版本以下的bug依然存在,同时,被打上[[DontEnum]]的属性有:toString,valueOf,constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable

最后,检测这个bug就更简单了,
  var isDontEnum = (function(){
    for (var p in { toString: 1 }) {
      if (p === 'toString') return false;
    }
    return true;
  })();

 

那么,如何修复这个BUG呢?

1 /*@cc_on if(o.toString!=={}.toString){
2  // doStuff ... for example
3  alert(o.toString);
4 }@*/

 

Dean Edwards

1 /*@cc_on
2 if(o.toString!==Object.prototype.toString){
3  // doStuff
4 }
5 if(o.valueOf!==Object.prototype.valueOf){
6  // doStuff
7 }
8 @*/

 参考:

http://webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html