如何在Array.prototype和Object.prototype的javascript中定义方法,以便它不出现在循环中

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

Array.prototype.find = function(testFun) { // code to find element in array }; 

所以我可以这样做:

 var arr = [1, 2, 3]; var found = arr.find(function(el) { return el > 2; }); 

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

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

这将使任何依赖于for in人都显示值(尤其是对象)。 更高版本的JavaScript有.map和.filter函数内置到数组中,但不会显示for in循环中。 我怎样才能创build更多的方法,不会出现在for in循环?

这很简单:不要使用数组的for-in循环 。 指责所有其他人这样做 – 这是一个很好的片段 ,告诉他们在发展过程中。

当然,如果在generics函数中进行枚举并且不知道他是否获取了数组,普通对象或带有自定义原型的对象,则可以使用hasOwnProperty如下所示:

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

注意显式使用Object.prototype来获取函数 – 可能有对象覆盖它(特别是在数据映射中,该值可能不是函数), 不支持它的对象或不能inheritance的对象对象。原型。 另见这里 。

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

一个有趣的,但Mozilla的方法将通过__iterate__覆盖数组枚举的行为,如此处所示 。

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

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

取决于您的限制:

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

阅读更多关于Object.defineProperty的信息https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty

这是因为必须检查hasOwnProperty

 for (var prop in arr) { if (arr.hasOwnProperty(prop)) { console.log(prop) } } 

现在这个日志1,2,3。