【问题标题】:Javascript extend prototype, and for-inJavascript 扩展原型和 for-in
【发布时间】:2013-12-02 07:33:42
【问题描述】:

我尝试在 Array 原型中添加一些我经常使用的新功能。我的问题是,当我向对象的原型添加一些东西,并在我创建的任何新数组(对象)的 for-in 循环中跟踪属性时,那些仅添加到原型中的新函数也会被列出?他们不应该只是在 proto 中吗?

举例: 所以我在原型中添加了一个“first”的功能。

Array.prototype.first = function() { return this[0]; }

所以当我现在使用 for-in 循环遍历数组时,我得到了命名函数,以及数组中的任何其他项。

var array = [1,2,3];   

//traces out: 1,3,4,first
for(var i in array) {
   console.log(i);
}

这仅仅是由于跟踪和/或使用 for-in 迭代对象而产生的吗?

【问题讨论】:

    标签: javascript object for-in-loop prototype-oriented


    【解决方案1】:

    您不应该使用 for-in 循环来循环数组。

    for (var i = 0, len = arr.length; i < len; ++i) {
    }
    

    for in 用于迭代对象的键。

    【讨论】:

    • 为什么不呢? (合法问题)
    • 使用 for 循环遍历数组是有意义的,但是如果我要遍历一个对象,我认为它仍然会打印出相同的内容。
    • 因为当你扩充数组原型时,你会得到那些额外的属性。此外,它的速度要快得多:jsperf.com/forin-forlength
    • Evan,感谢您的回复,以及性能测试的链接。
    【解决方案2】:

    埃文是正确的。但是,在 javascript 中使用 for..in 语句时,最好始终测试当前属性是对象的属性,而不是从原型链继承的属性:

    for(var attr in obj){
       if(obj.hasOwnProperty(attr)){
           // first will not appear here
       }
    }
    

    【讨论】:

    • 啊,我明白了。因此,使用 hasOwnProperty() 仅检查属性与从原型链继承的属性。感谢罗布的回复。
    • 我很高兴,这让很多人感到困惑。 Maurice 说扩展原生 js 对象的原型被认为是不好的做法也是正确的。 en.wikipedia.org/wiki/Prototype_JavaScript_Framework#Problems
    • 在这里,我正要向数组、字符串和日期添加一堆原型。但是,如果您使它们不可枚举,就像莫里斯的回答一样,将原型添加到本机对象的真正危险是什么?我猜如果您使用与包含库中的其他函数名称相同的函数名称扩展原型,那么原始原型会被覆盖还是什么?这是我唯一想到的。
    • 名称冲突是主要问题之一,根据您扩展的内容,它还会增加大量开销。可以在此处找到有关此主题的深入文章:perfectionkills.com/whats-wrong-with-extending-the-dom
    【解决方案3】:

    如果你真的需要这样做,请使用

    Object.defineProperty(Array.prototype, 'first', {
        value: function() { return this[0]; },
        enumerable: false
    });
    

    但有些人认为这是一种不好的做法。做之前三思而后行。

    【讨论】:

    • 感谢 Maurice 指出这一点,以及在需要时的替代方法。
    • 至于不做的原因: 1. 通常for in 中断(你修复了但不是所有浏览器都支持它,不能polyfill)。 2.与未来的浏览器实现或其他代码冲突。
    • @leetou 另一种方法是创建一个名为 first 的函数并像这样调用它:first.call(someArray); 也许以下链接会对您有所帮助:stackoverflow.com/a/16063711/1641941
    猜你喜欢
    • 2021-01-27
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多