【问题标题】:JS prototype returns prototype codeJS原型返回原型代码
【发布时间】:2011-01-25 04:36:25
【问题描述】:
Array.prototype.last = function() { if(this.length !=0) return this[this.length-1]; }
myarray = new Array(1,2,3);
  for(var i in myarray){
  alert(i+'='+myarray[i]);
}

当上述代码执行时,它会正确地提醒每个循环,但最后会弹出另一个警报,其中包含 Array.prototype.last 方法的来源。

每当我定义任何原型方法时都会发生这种情况,我只是不知道为什么!

所以我收到警报:0=1,1=2,2=3,然后收到一个警报:

last=function () {
  if (this.length != 0) {
    return this[this.length - 1];
  }
}

【问题讨论】:

    标签: javascript prototype


    【解决方案1】:

    这是因为for-in 语句枚举对象属性,包括继承的属性。

    这就是为什么将 for-in 语句与数组或 类数组 对象一起使用被认为是一种不好的做法的原因之一。

    其他原因包括规范不保证枚举的顺序,这意味着索引属性可能不会按数字顺序访问,例如:

    var a = [];
    a[1] = 'b';
    a[0] = 'a'
    
    for (var prop in a) { console.log(i); }
    

    大多数浏览器会检测到您正在尝试迭代数组,并且将按数字顺序访问属性,但在 IE 中,将按创建属性的顺序枚举属性,1,然后是0

    还知道for-in 语句可能比简单的顺序循环慢,因为正如您现在所知,它需要自省对象的整个原型链,以枚举继承的成员。

    作为一般建议,始终使用顺序循环来迭代这种对象。

    另见:

    【讨论】:

    • 啊,好吧,我想当你知道时这很明显,但我发现 for(var in array) 比 for (var i = 0; i
    • @Crankshaft:你可以使用 jQuery $.each() 即 $.each(myarray,function(index,value){alert(value);}) 来避免这个问题。
    【解决方案2】:

    这就是为什么你从不在 javascript 中使用 for(idx in anArray){...} 的原因,for...in 循环会迭代 所有 object 中的属性,而 Array 只是 object在 JS 中,您为 Array 的所有实例添加了一个新属性,因此它显示为 for 循环中的索引之一。

    通常你应该使用数组:

    for(var i=0 ; i< anArray.length ; i++){
        //do stuff
    }
    

    【讨论】:

    • 更准确地说,他在 Array 的原型中添加了一个属性,该属性可以被 Array 的每个实例枚举和继承。在这与“为每个实例添加属性”之间进行一点澄清。
    • @Ken,有吗?这样想,通过将它添加到原型中,这个属性是否不能从Array 的所有当前和未来实例中获得? JS 中原型的语义是这样的,我不认为该陈述不正确或具有误导性。
    • 当我第一次阅读“数组的所有实例的新属性”时,我看到了潜在的歧义,例如每个实例实际上都有自己的 tha 值副本,而不是从一个共同的地方继承它。不是每个人都了解原型是如何工作的,所以我不喜欢为(错误)解释留出空间;)您显然知道您在说什么,但并不是每个人都可能从您最初的措辞中收集到它。 'sallimsayin.
    • 但是他们确实都有自己的副本(在对象的情况下它可能是引用的副本,但'slot'不共享)一旦它们是实例化 - 尝试 Array.prototype.foo="bar" 然后实例化几个数组并更改它们的 foo 值......它们保持独立。如果您使用对象而不是字符串,您可以共享对该对象成员的更改,因为每个 Array 都有自己的对象引用副本(这在 JS 中通常会令人困惑 - 一切都是按值传递...对象除外)
    【解决方案3】:

    这是因为 last 是 myarray 从原型属性派生的一个函数,并且是可索引的。为避免这种情况,您需要检查 hasOwnProperty 即:

    for(var i in myarray)
    {
      if(myarray.hasOwnProperty(i))
        alert(i+'='+myarray[i]); 
    }
    

    【讨论】:

    • +1 用于正确解释原型继承和可枚举性以及 hasOwnProperty,但更好的是避免使用 for...in 进行数组迭代。
    • @Ken:谢谢。同意。 @Someone:我很想知道投反对票的原因。
    • 也许他们认为我太慷慨了,因为数组继续使用 for...in。 =/
    猜你喜欢
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    相关资源
    最近更新 更多