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

时间:2022-04-07 18:30:57

【题记】每次看《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都显示如下:

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

而IE8,6,7显示如下:

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

可见,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