You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何区分原生原型与扩展原型,遍历数组时跳过扩展属性?

这是个非常常见的JS坑——for...in会遍历对象自身以及原型链上的所有可枚举属性,所以你添加到Array.prototype的repeat方法也被当成遍历项输出了。下面给你几种实用的解决办法:

1. 用hasOwnProperty()过滤原型属性

hasOwnProperty()是对象的原生方法,专门用来判断属性是否属于对象自身(而非从原型链继承)。修改你的循环代码即可:

var model = { features:[1,2,3] }; 
for (var p in model.features) { 
  // 只处理数组自身的属性
  if (model.features.hasOwnProperty(p)) {
    console.log(p); 
  }
}

这样就能精准跳过原型上的repeat,只打印数组自身的索引。

2. 用Object.keys()遍历自身可枚举属性

ES6引入的Object.keys()会返回对象自身所有可枚举属性的数组,完全不会包含原型链上的内容。结合forEach遍历更简洁:

var model = { features:[1,2,3] }; 
Object.keys(model.features).forEach(function(p) {
  console.log(p);
});

这种写法比for...in加判断更符合现代JS的风格,也更不容易出错。

3. 直接用数组原生遍历方法(推荐)

既然你遍历的是数组,优先用数组专属的遍历方法才是正道——比如forEach、for...of,它们只会遍历数组的元素/索引,完全不会碰原型链上的属性:

// 如果想打印数组元素(对应你预期的1、2、3)
model.features.forEach(function(item) {
  console.log(item);
});

// 如果想打印索引(0、1、2)
for (const index of model.features.keys()) {
  console.log(index);
}

这种方法从根源上避开了for...in的原型遍历问题,逻辑也更清晰。

4. 从源头阻止自定义原型属性被枚举(可选)

如果这个repeat方法是你自己添加的(或者能协调第三方库修改),可以用Object.defineProperty()定义属性——它默认会把属性设为不可枚举:

Object.defineProperty(Array.prototype, 'repeat', {
  value: function(value, length) { 
    while (length) this[--length] = value; 
    return this; 
  },
  // 显式声明不可枚举(默认就是false,写出来更直观)
  enumerable: false
});

这样即使你用for...in遍历数组,也不会出现repeat这个属性了。

内容的提问来源于stack exchange,提问作者ParoX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:33:42