如何在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。