如何在javascript中定义Array.prototype和Object.prototype上的方法,使其不';不在循环中出现

如何在javascript中定义Array.prototype和Object.prototype上的方法,使其不';不在循环中出现,javascript,function,Javascript,Function,我想在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循环中对数组

我想在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
循环中显示。我如何才能创建更多类似这样的方法,而这些方法不会出现在
for in
循环中?

这是因为我必须检查
hasOwnProperty

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

现在记录1、2、3。

这是因为必须检查
hasOwnProperty

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

现在,此日志记录1、2、3。

取决于您的限制:

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

阅读有关对象的更多信息。此处定义属性

,具体取决于您的限制:

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

阅读更多关于对象的信息。在这里定义属性很简单:不要使用。责怪所有这样做的人——在开发过程中告诉他们

当然,如果在泛型函数中执行枚举,但不知道是获取数组、普通对象还是具有自定义原型的对象,则可以这样使用:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something
Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});
请注意显式使用
Object.prototype
来获取函数-可能存在覆盖它的对象(特别是在数据映射中,该值甚至可能不是函数)、从Object.prototype继承的对象或根本不从Object.prototype继承的对象。另见

然而,只有意识到这个问题的脚本作者才会过滤所有的for-in循环——有些人这样做只是因为——而且大多是错误的,他应该使用for-loop数组迭代。但我们的问题是那些不知道的作者

一种有趣但仅限于Mozilla的方法是通过覆盖数组上枚举的行为,如

幸运的是,EcmaScript 5.1允许我们将属性设置为不可枚举。当然,这在旧的浏览器中是不受支持的,但是为什么还要麻烦呢?无论如何,我们都需要使用所有酷的高阶数组元素:-)如下所示:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something
Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});

这很简单:不要使用。责怪所有这样做的人——在开发过程中告诉他们

当然,如果在泛型函数中执行枚举,但不知道是获取数组、普通对象还是具有自定义原型的对象,则可以这样使用:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something
Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});
请注意显式使用
Object.prototype
来获取函数-可能存在覆盖它的对象(特别是在数据映射中,该值甚至可能不是函数)、从Object.prototype继承的对象或根本不从Object.prototype继承的对象。另见

然而,只有意识到这个问题的脚本作者才会过滤所有的for-in循环——有些人这样做只是因为——而且大多是错误的,他应该使用for-loop数组迭代。但我们的问题是那些不知道的作者

一种有趣但仅限于Mozilla的方法是通过覆盖数组上枚举的行为,如

幸运的是,EcmaScript 5.1允许我们将属性设置为不可枚举。当然,这在旧的浏览器中是不受支持的,但是为什么还要麻烦呢?无论如何,我们都需要使用所有酷的高阶数组元素:-)如下所示:

for (var prop in anyObj )
    if (Object.prototype.hasOwnProperty.call(anyObj, prop))
        // do something
Object.defineProperty(Array.prototype, "find", {
    enumerable: false,
    writable: true,
    value: function(testFun) {
        // code to find element in array
    }
});

上述答案没有抓住一个要点:

可枚举的默认为false。()


因此,只需使用
Object.defineProperty(Array.prototype,'myFunc'myFunc)
而不是
Array.prototype.myFunc=myFunc
就可以解决这个问题。

上述答案没有抓住要点:

可枚举的默认为false。()


因此,只需使用
Object.defineProperty(Array.prototype,'myFunc'myFunc)
而不是
Array.prototype.myFunc=myFunc
即可解决问题。

这正是不在数组上使用for in循环的原因!这正是不在阵列上使用for in循环的原因!不,您不想为此原型方法定义getter函数。看看我的答案……你不能相信其他使用你的代码的人会做hasOwnProperty检查,所以这是一种安全的方法。不,你不想为这个原型方法定义一个getter函数。看看我的答案…你不能相信任何使用你的代码的人会做hasOwnProperty检查,所以这是一种安全的方法。我喜欢把那长的hasOwnProperty放在助手函数中。拥有像
hop(anyObj,prop)
这样的速记让我不太可能使用您提到的较短但次优的备选方案之一。当然,您可以定义
var-hop=Function.prototype.call.bind(Object.prototype.hasOwnProperty)
,但作为普通程序员,我从来都不需要它。当然,那些提供高度泛型函数的库在内部使用它。我喜欢将长hasown属性放在助手函数中。拥有像
hop(anyObj,prop)
这样的速记让我不太可能使用您提到的较短但次优的备选方案之一。当然,您可以定义
var-hop=Function.prototype.call.bind(Object.prototype.hasOwnProperty)
,但作为普通程序员,我从来都不需要它。当然,那些提供高度通用函数的库在内部使用它。bergi试图说,如果有人向arr或其原型添加“hasOwnProperty”属性,则此代码将中断。bergi试图说,如果有人向arr或其原型添加“hasOwnProperty”属性,则此代码将中断。