如何在 Array.prototype 和 Object.prototype 上的 javascript 中定义方法,使其不会出现在 for in 循环中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13296340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop
提问by wbrady
I want to define helper methods on the Array.prototype and Object.prototype. My current plan is to do something like:
我想在 Array.prototype 和 Object.prototype 上定义辅助方法。我目前的计划是做这样的事情:
Array.prototype.find = function(testFun) {
// code to find element in array
};
So that I can do this:
这样我就可以做到这一点:
var arr = [1, 2, 3];
var found = arr.find(function(el) { return el > 2; });
It works fine but if I loop over the array in a for in
loop the methods appear as values:
它工作正常,但如果我在循环中遍历数组,for in
则方法显示为值:
for (var prop in arr) { console.log(prop); }
// prints out:
// 1
// 2
// 3
// find
This will screw up anybody else relying on the for in
to just show values (especially on Objects). The later versions of javascript have .map and .filter functions built into arrays but those don't show up on for in
loops. How can I create more methods like that which won't show up in a for in
loop?
这将搞砸任何依赖for in
仅显示值的人(尤其是在对象上)。较新版本的 javascript 将 .map 和 .filter 函数内置到数组中,但这些函数不会出现在for in
循环中。如何创建更多不会出现在for in
循环中的方法?
回答by Bergi
It's quite easy: Don't use for-in loops with Arrays. Blame everybody else who does so - here is a nice snippetto tell them during development.
这很简单:不要对 Arrays使用for-in 循环。责怪其他这样做的人 -这是一个很好的片段,可以在开发过程中告诉他们。
Of course, if one does an enumeration in a generic function and doesn't know whether he gets an array, a plain object or an object with a custom prototype, you can use hasOwnProperty
like this:
当然,如果在泛型函数中进行枚举并且不知道他得到的是数组、普通对象还是具有自定义原型的对象,则可以hasOwnProperty
像这样使用:
for (var prop in anyObj )
if (Object.prototype.hasOwnProperty.call(anyObj, prop))
// do something
Notice the explicit use of Object.prototype
to get the function - there might be objects that overwrite it (especially in data-maps, the value might not even be a function), objects that do not support itor objects that do not inherit from Object.prototype at all. See also here.
注意Object.prototype
获取函数的显式使用- 可能有对象覆盖它(特别是在数据映射中,值甚至可能不是函数)、不支持它的对象或不从 Object.prototype 继承的对象根本。另请参见此处。
Yet, only a script author who is aware of the problem would filter all his for-in-loops - and some only do it because it gets recommended- and does it mostly wrong, he should have used a for-loop array iteration instead. But our problem are those authors who do not know of it.
然而,只有知道这个问题的脚本作者才会过滤他所有的 for-in-loops - 有些人只是因为它被推荐而这样做 - 而且它大多是错误的,他应该使用 for 循环数组迭代来代替。但我们的问题是那些不知道它的作者。
An interesting, but Mozilla-only approach would be overwriting the behavior of enumerations on arrays via __iterate__
, as demonstrated here.
一个有趣但仅限 Mozilla 的方法是通过 覆盖数组上的枚举行为__iterate__
,如此处所示。
Fortunately, EcmaScript 5.1 allows us setting properties to be non-enumerable. Of course, this is not supported in older browsers, but why bother? We'd need to use es5-shimsanyway for all the cool higher-order array stuff :-) Use defineProperty
like this:
幸运的是,EcmaScript 5.1 允许我们将属性设置为不可枚举。当然,这在旧浏览器中是不支持的,但何必呢?对于所有很酷的高阶数组内容,我们无论如何都需要使用es5-shims:-)defineProperty
像这样使用:
Object.defineProperty(Array.prototype, "find", {
enumerable: false,
writable: true,
value: function(testFun) {
// code to find element in array
}
});
回答by cbayram
Depending on your restrictions:
根据您的限制:
// In EcmaScript 5 specs and browsers that support it you can use the Object.defineProperty
// to make it not enumerable set the enumerable property to false
Object.defineProperty(Array.prototype, 'find', {
enumerable: false, // this will make it not iterable
get: function(testFun) {
// code to find element in array
};
});
Read more about Object.definePropertyhere https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
在此处阅读有关Object.defineProperty 的更多信息https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty
回答by mvbl fst
It's because have to check for hasOwnProperty
:
这是因为必须检查hasOwnProperty
:
for (var prop in arr) {
if (arr.hasOwnProperty(prop)) {
console.log(prop)
}
}
Now this logs 1, 2, 3.
现在这记录了 1、2、3。
回答by junvar
The above answers miss a point:
上面的答案忽略了一点:
enumerable ... Defaults to false. (mdn)
enumerable ...默认为 false。( mdn)
So simply using Object.defineProperty(Array.prototype, 'myFunc' myFunc)
instead of Array.prototype.myFunc = myFunc
will resolve the issue.
所以简单地使用Object.defineProperty(Array.prototype, 'myFunc' myFunc)
而不是Array.prototype.myFunc = myFunc
将解决问题。