具有扩展原型和"for-in"循环的 JavaScript 本机对象



我已经扩展了Array原型:

if(typeof Array.prototype.filter === 'undefined') Array.prototype.filter = function(fun /*, thisp*/){
  var len = this.length;
  if(typeof fun != "function") throw new TypeError();
  var res = [], thisp = arguments[1];
  for(var i=0;i<len;i++){
    if(i in this){
      var val = this[i]; // in case fun mutates this
      if(fun.call(thisp, val, i, this)) res.push(val);
    }
  }
  return res;
};

例如,我创建了一个数组:

var A = [ 1, 2, 3, 4, 5 ];

然后我添加了额外的属性,我将使用:

A.creator = 'Rustam';
A.created = new Date();

如果我将使用for-in循环,并且浏览器没有内置对Array.filter的支持,那么它将通过A.filter

我知道这一点:

for(var p in A) {
  if (!A.hasOwnProperty(p)) continue
  console.log(p)
};

有没有一种方法可以在不使用hasOwnProperty的情况下将A.filter隐藏在for-in


更新以回答浏览器支持:

  • IE9+
  • FF4+
  • 歌剧11.6+
  • Safari 5+

要定义一个不显示在循环中的属性,请使用Object.defineProperty:

Object.defineProperty(Array.prototype, 'filter', {value:'XYZ'});

这用一个名为filter的属性扩展了Array.prototype,该属性具有默认的属性描述符,包括enumerable: false,这会导致该属性不显示在for( .. in ..)循环中。

参考文献

  • MDN的Object.defineProperty
  • MSDN上的Object.defineProperty

PS:不会在旧浏览器上工作我没有此API的浏览器兼容性矩阵。

最新更新