简体   繁体   English

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

[英]Javascript: hiding prototype methods in for loop?

So lets say I've added some prototype methods to the Array class:所以假设我已经向数组 class 添加了一些原型方法:



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;
}

then I create an associative array and attempt to loop through it's keys:然后我创建一个关联数组并尝试遍历它的键:



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

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

this returns five items:这将返回五个项目:

  -One
  -Two
  -Three
  -containsKey
  -containsValue

but I want (expect?) only three.但我想要(预计?)只有三个。 Am I approaching this wrong?我接近这个错误吗? is there a way to "hide" the prototype methods?有没有办法“隐藏”原型方法? or should I be doing something differently?还是我应该做些不同的事情?

You can use JavaScript's hasOwnProperty method to achieve this in the loop, like this: 你可以使用JavaScript的hasOwnProperty方法在循环中实现这一点,如下所示:

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

Reference: This YUI blog article . 参考: 这个YUI博客文章

You can achieve desired outcome from the other end by making the prototype methods not enumerable: 通过使原型方法不可枚举,您可以从另一端获得所需的结果:

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

This usually works better if you have control over method definitions, and in particular if you have no control over how your code will be called by other people, which is a common assumption in library code development. 如果您可以控制方法定义,这通常会更好,特别是如果您无法控制其他人如何调用您的代码,这是库代码开发中的常见假设。

Javascript doesn't support associative arrays the way you think they do. Javascript不像你认为的那样支持关联数组。 http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful http://ajaxian.com/archives/javascript-associative-arrays-considered-harmful

for (var i in .. gets all of the properties of an object (an array is just another object) which is why you're seeing the other objects you've prototyped to it. for(var i in ..获取对象的所有属性(数组只是另一个对象),这就是为什么你会看到你原型化的其他对象的原因。

As the article suggests you should use an object: 正如文章建议你应该使用一个对象:


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

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

you could do this: 你可以这样做:

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

But that's a shoddy workaround 但那是一种伪劣的解决方法

Method 1 : use Object.keys (which doesn't return prototype properties) & loop 方法1 :使用Object.keys (不返回原型属性)和循环

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

Method 2 : hasOwnProperty inside a for-loop. 方法2 :在for循环中使用hasOwnProperty

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

For high-performance iteration over JavaScript arrays, use either a for or while loop. 对于JavaScript数组的高性能迭代,请使用forwhile循环。 Nicholas Zakas discusses the most-performant options for iterating over arrays in his Tech Talk Speed Up Your JavaScript . Nicholas Zakas在他的Tech Talk 加速你的JavaScript中讨论了迭代数组的最高性能选项。

Your best bet is probably something like this: 你最好的选择可能是这样的:

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

This approach will be peform best for a few reasons: 由于以下几个原因,这种方法最好:

  • Only a single local variable is allocated 仅分配了一个局部变量
  • The collection's length property is only accessed once, at the initialization of the loop 集合的length属性仅在循环初始化时访问一次
  • Each iteration, a local is compared to a constant ( i >= 0 ) instead of to another variable 每次迭代时,将local与常量( i >= 0 )进行比较,而不是与另一个变量进行比较

You can hide methods that added to prototype from for-in loops like this:您可以像这样从 for-in 循环中隐藏添加到原型的方法:

Object.defineProperty(Array.prototype, "containsKey", { enumerable: false });

Just after you add method.就在你添加方法之后。 where the "containsKey" is your added method.其中“containsKey”是您添加的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM