【问题标题】:Add methods to Array.prototype, without the side effects向 Array.prototype 添加方法,没有副作用
【发布时间】:2014-04-18 17:26:54
【问题描述】:

我想在数组上添加一个“插入”方法。 所以我这样做:

> Array.prototype.insert = function(index, element){
    this.splice(index, 0, element);
};

它的工作原理:

> a = [1,2,3]
[1, 2, 3]
> a.insert(0, 4)
undefined
> a
[4, 1, 2, 3]

但是有一个不受欢迎的副作用:

> for (i in a){console.log(i)}
0
1
2
3
insert

> for (i in a){console.log(a[i])}
4
1
2
3
function (index, element){
    this.splice(index, 0, element);
}

这种行为不是故意的,会破坏我使用的其他库。 有什么优雅的解决方案吗?

【问题讨论】:

  • 这就是为什么你永远不应该在数组上使用for..in
  • 您仍然可以使用for 循环的其他构造:for ( var i = 0; i < a.length; i++ ) { console.log(a[i]); }
  • 同意!但是现在我们倾向于重用很多其他人的代码,并且很难确保所有库都遵循这一规则。
  • 事实上,这是反对做你想做的事情的一个很好的论据。不要修改您不拥有的对象。 nczonline.net/blog/2010/03/02/…

标签: javascript prototype for-in-loop


【解决方案1】:

Object.defineProperty 有效,但在旧版浏览器中不支持。 (compatibility table)

Object.defineProperty(Array.prototype, 'insert', {
  enumerable: false,
  value: function(index, element){
    this.splice(index, 0, element);
  }
});

Demonstration

【讨论】:

  • 它有效,谢谢!!你碰巧在任何地方都有它的兼容性表吗?
【解决方案2】:

在这个循环中继承的属性(插入方法)不显示。

  for (i in a){if (a.hasOwnProperty(i)) {console.log(i)}}

因此,从 Object 继承的每个对象都继承了 hasOwnProperty 方法。该方法可用于判断一个对象是否具有指定属性作为该对象的直接属性;与 in 运算符不同,此方法不会检查对象的原型链。

此方法兼容所有浏览器

【讨论】:

  • 对我不起作用。我不愿意更改我页面上导入的 js 库中的循环样式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 2015-03-01
  • 2011-01-25
  • 1970-01-01
  • 2021-07-25
  • 2012-09-23
  • 2020-04-09
相关资源
最近更新 更多