如何在 Array.prototype 和 Object.prototype 上的 javascript 中定义方法,使其不会出现在 for in 循环中 [英] How to define method in javascript on Array.prototype and Object.prototype so that it doesn't appear in for in loop

查看:25
本文介绍了如何在 Array.prototype 和 Object.prototype 上的 javascript 中定义方法,使其不会出现在 for in 循环中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 Array.prototype 和 Object.prototype 上定义辅助方法.我目前的计划是做这样的事情:

I want to define helper methods on the Array.prototype and Object.prototype. My current plan is to do something like:

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

它工作正常,但如果我在 for in 循环中遍历数组,则方法显示为值:

It works fine but if I loop over the array in a for in loop the methods appear as values:

for (var prop in arr) { console.log(prop); }
// prints out:
// 1
// 2
// 3
// find

这会使依赖 for in 只显示值(尤其是对象)的其他人搞砸.较新版本的 javascript 将 .map 和 .filter 函数内置到数组中,但这些函数不会出现在 for in 循环中.如何创建更多不会出现在 for in 循环中的方法?

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 循环数组.责怪其他这样做的人 - 这里有一个很好的片段可以在开发过程中告诉他们.

It's quite easy: Don't use for-in loops with Arrays. Blame everybody else who does so - here is a nice snippet to tell them during development.

当然,如果在泛型函数中进行枚举,不知道得到的是数组、普通对象还是带有自定义原型的对象,可以使用hasOwnProperty 像这样:

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:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something

注意显式使用 Object.prototype 来获取函数 - 可能有对象覆盖它(特别是在数据映射中,值甚至可能不是函数),不支持 或根本不从 Object.prototype 继承的对象.另请参阅此处.

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 it or objects that do not inherit from Object.prototype at all. See also here.

然而,只有知道这个问题的脚本作者才会过滤他所有的 for-in-loops - 有些只是因为 它被推荐 - 并且它大部分是错误的,他应该使用for循环数组迭代来代替.但我们的问题是那些不知道它的作者.

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.

一种有趣但仅限 Mozilla 的方法是通过 __iterate__,如此处演示.

An interesting, but Mozilla-only approach would be overwriting the behavior of enumerations on arrays via __iterate__, as demonstrated here.

幸运的是,EcmaScript 5.1 允许我们将属性设置为不可枚举.当然,这在旧浏览器中是不支持的,但何必呢?无论如何,我们需要使用 es5-shims 来处理所有很酷的高阶数组内容:-) 使用 defineProperty 像这样:

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-shims anyway for all the cool higher-order array stuff :-) Use defineProperty like this:

Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});

这篇关于如何在 Array.prototype 和 Object.prototype 上的 javascript 中定义方法,使其不会出现在 for in 循环中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆