【问题标题】:Javascript: hiding prototype methods in for loop?Javascript:在for循环中隐藏原型方法?
【发布时间】:2010-11-09 14:39:41
【问题描述】:

假设我在 Array 类中添加了一些原型方法:



Array.prototype.containsKey = function(obj) {
    for(var key in this)
        if (key == obj) return true;
    return false;
}

Array.prototype.containsValue = function(obj) {
    for(var key in this)
        if (this[key] == obj) return true;
    return false;
}

然后我创建一个关联数组并尝试遍历它的键:



var arr = new Array();
arr['One'] = 1;
arr['Two'] = 2;
arr['Three'] = 3;

for(var key in arr)
   alert(key);

这会返回五个项目:

-一 -二 -三 -containsKey -包含值

但我想要(预计?)只有三个。我接近这个错误吗?有没有办法“隐藏”原型方法?还是我应该做一些不同的事情?

【问题讨论】:

标签: javascript arrays prototype loops for-loop


【解决方案1】:

您可以通过使原型方法不可枚举来从另一端获得期望的结果:

Object.defineProperty(Array.prototype, "containsKey", {
  enumerable: false,
  value: function(obj) {
      for(var key in this)
        if (key == obj) return true;
      return false;
    }
});

如果您可以控制方法定义,尤其是如果您无法控制其他人如何调用您的代码(这是库代码开发中的常见假设),这通常会更好。

【讨论】:

【解决方案2】:

你可以在循环中使用JavaScript的hasOwnProperty方法来实现,像这样:

for(var key in arr) {
    if (arr.hasOwnProperty(key)) {
        ...
    }
}

参考:This YUI blog article

【讨论】:

  • 具有讽刺意味的是,我尝试创建一个较短版本的 hasOwnProperty Object.prototype.has = Object.prototype.hasOwnProperty 时遇到了这个问题
  • 显然直接在对象上调用 hasOwnProperty 被认为是不安全的 (reference)。安全的方法是Object.prototype.hasOwnProperty.call(foo, "bar")
【解决方案3】:

Javascript 并不像您认为的那样支持关联数组。 http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for (var i in .. 获取对象的所有属性(数组只是另一个对象),这就是为什么您会看到其他对象的原型。

正如文章建议你应该使用一个对象:


var assoc = {'One' : 1, 'Two' : 2};
assoc['Three'] = 3;

for(var key in assoc)
   alert(key+' => '+assoc[key]);

【讨论】:

    【解决方案4】:

    你可以这样做:

    for(var key in arr)
    {
       if (typeof(arr[key]) == "function")
          continue;
       alert(key);
    }
    

    但这是一个伪劣的解决方法

    【讨论】:

      【解决方案5】:

      方法一:使用Object.keys(不返回原型属性)&循环

      Object.keys(arr); // ['One', 'Two', 'Three']
      Object.keys(arr).forEach(key => console.log(key))
      

      方法 2hasOwnProperty 在 for 循环内。

       for(var key in arr) {
         if (arr.hasOwnProperty(key)) {
           ...
         }
       }
      

      【讨论】:

        【解决方案6】:

        对于 JavaScript 数组的高性能迭代,请使用 forwhile 循环。 Nicholas Zakas 在他的技术讲座Speed Up Your JavaScript 中讨论了迭代数组的最佳性能选项。

        你最好的选择可能是这样的:

        for (var i = collection.length - 1; i >= 0; i--) {
          if (obj == collection[i]) return true;
        }
        

        由于以下几个原因,这种方法会表现得最好:

        • 只分配一个局部变量
        • 集合的length 属性仅在循环初始化时访问一次
        • 每次迭代,都会将局部变量与常量 (i >= 0) 进行比较,而不是与另一个变量进行比较

        【讨论】:

        • 鉴于他使用数组的方式,您不能像那样进行迭代,因为他没有使用数字作为键,因此当他将其称为 collection[1] 时,collection[1] 将不存在一个']
        • 这倒退了,v8 无法优化。您应该始终以正确的方式向前迭代。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-07-20
        • 2018-05-05
        • 1970-01-01
        • 2017-03-05
        • 2017-06-13
        • 2013-07-03
        • 2021-08-17
        相关资源
        最近更新 更多