防止新的prototyped方法出现在for对象中的for循环中

时间:2015-05-22 08:26:17

标签: javascript

我有一个功能,我想让它可用于所有对象。 它的mergeObject(object)函数定义如下:

Object.prototype.mergeObjects = function(object){
    if (typeof object != "object") return;
    for(var key in object){
        if (object.hasOwnProperty(key))
            this[key] = object[key];
    }
    return this;
}

我有一个变量事件:

events : {
    "click #retryBtn":"onRetryBtnClick",
    "click #cancelBtn":"onCancelBtnClick",
    "click .dialogButton":"onDialogBtnClick"
}

这是骨干的事件json Object。

当我尝试为事件中的键运行for循环时

for (var key in events) 
{
    console.log(key) 
}

打印出来

click #retryBtn
click #cancelBtn
click .dialogButton
mergeObjects

我不明白为什么我将“mergeObjects”作为“events”对象中的键。

事件对象的结构是:

click #cancelBtn: "onCancelBtnClick"
click #retryBtn: "onRetryBtnClick"
click .dialogButton: "onDialogBtnClick"
__proto__: Object
    __defineGetter__: function __defineGetter__() { [native code] }
    __defineSetter__: function __defineSetter__() { [native code] }
    __lookupGetter__: function __lookupGetter__() { [native code] }
    __lookupSetter__: function __lookupSetter__() { [native code] }
    constructor: function Object() { [native code] }
    hasOwnProperty: function hasOwnProperty() { [native code] }
    isPrototypeOf: function isPrototypeOf() { [native code] }
    mergeObjects: function (object){                 
    propertyIsEnumerable: function propertyIsEnumerable() { [native code] }
    toLocaleString: function toLocaleString() { [native code] }
    toString: function toString() { [native code] }
    valueOf: function valueOf() { [native code] }
    get __proto__: function __proto__() { [native code] }
    set __proto__: function __proto__() { [native code] }

任何人都可以解释为什么“mergeObject”是for循环键的一部分吗?

我该如何避免它?由于还有其他方法,如“__defineGetter”,它们没有出现在for循环键中。

2 个答案:

答案 0 :(得分:1)

mergeObjects是可枚举的属性(意思是可以使用for来访问),events}对象继承该属性,而像__defineGetter这样的方法是不可枚举的(可以' t可以通过in访问。

for in循环遍历对象的所有可枚举属性,包括原型链中的属性。

使用hasOwnProperty来避免继承的属性,并且只获取直接的可枚举属性。

for (var key in events) 
{
    if(events.hasOwnProperty(key))
    console.log(key) 
}

如果您希望对象的所有直接属性可枚举或不可枚举(使用defineProperty使用可枚举的假设置),那么您应该迭代Object.getOwnPropertyNames()(IE9 +),如

var keys = events.getOwnPropertyNames(); 
for(var i=0;i<keys.length;i++)
{
    console.log(keys[i]) 
}
/*
Or using forEach
events.getOwnPropertyNames().forEach(function(key){
    console.log(key);
})
*/    

其他链接https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties

编辑:为了不在{in循环中获取mergeObjects,请使用Object.defineProperty和可枚举的错误

Object.defineProperty(Object.prototype, 'mergeObjects', {
  value: function(object){
             if (typeof object != "object") return;
                 for(var key in object){
                    if (object.hasOwnProperty(key))
                        this[key] = object[key];
                 }
             return this;
   },
   enumerable:false  //no need for this statement as default is false
});

适用于IE9及以上版本

答案 1 :(得分:0)

使用hasOwnProperty跳过继承的属性:

for (var key in events) 
{
    if (events.hasOwnProperty(key)) {
        console.log(key);
    }
}