Javascript:在for循环中隐藏原型方法?

时间:2009-07-10 04:22:10

标签: javascript arrays prototype loops for-loop

所以我想说我已经在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);

这会返回五个项目:

  -One
  -Two
  -Three
  -containsKey
  -containsValue

但我想(期待?)只有三个。我接近这个错吗?有没有办法“隐藏”原型方法?或者我应该做些不同的事情?

6 个答案:

答案 0 :(得分:48)

您可以使用JavaScript的hasOwnProperty方法在循环中实现此目的,如下所示:

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

参考:This YUI blog article

答案 1 :(得分:47)

通过使原型方法不可枚举,您可以从另一端获得理想的结果:

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

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

答案 2 :(得分:4)

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]);

答案 3 :(得分:2)

你可以这样做:

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

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

答案 4 :(得分:1)

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

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

方法2 :{ - 3}}在for-loop中。

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

答案 5 :(得分:0)

对于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)进行比较,而不是与另一个变量进行比较