使用hasOwnProperty的适当/推荐方法是什么?

时间:2017-01-12 02:16:42

标签: javascript

如果对象可以包含名为“hasOwnProperty”的自己的属性:

> a={abc: 123};
{ abc: 123 }
> a.hasOwnProperty("abc");
true
> a['hasOwnProperty'] = 1;
1
> a.hasOwnProperty("abc");
TypeError: a.hasOwnProperty is not a function
...

如果您考虑Object.keys(),Object.assign()ETC,那么这种工作方式有点难看。那么,还有更好的方法吗?

> Object.hasOwnProperty.call(a, "abc");
true
> Object.hasOwnProperty.call(a, "hasOwnProperty");
true

为什么解决方案不应该是唯一推荐的方式?直接使用对象中的方法似乎是失败的方法,特别是如果它包含外部数据(不在一个人的控制中)

3 个答案:

答案 0 :(得分:0)

使用hasOwnProperty的适当/推荐方法是作为过滤器,或确定对象是否具有该属性的方法。只是他们在你的第二个命令bash obfuscate_project中使用它。

通过用a.hasOwnProperty('abc')覆盖Object hasOwnProperty属性,虽然它是安全有效的,但只是删除了在该Object上使用hasOwnProperty函数的能力。

我在这里错过了你的真实问题吗?看起来你已经从你的例子中知道了这一点。

通过

  

'直接从对象使用方法似乎是一个失败的方法

你是指这样的东西:

a['hasOwnProperty'] = 1

因为这在很多方面非常有用,你可以想象。

答案 1 :(得分:0)

如果您可以使用ECMAScript 2015,可以尝试Reflect.getOwnPropertyDescriptor。 如果给定属性存在于对象上,则返回该属性描述符,否则为undefined。

为简化起见,您可以创建此功能:

var hasOwnProp = (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop) !== undefined;

var obj = new Object();
obj.prop = 'exists';

console.log('Using hasOwnProperty')
console.log('prop: ' + obj.hasOwnProperty('prop'));            
console.log('toString: ' + obj.hasOwnProperty('toString'));        
console.log('hasOwnProperty: ' + obj.hasOwnProperty('hasOwnProperty'));   

var hasOwnProp = (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop) !== undefined;

console.log('Using getOwnPropertyDescriptor')
console.log('prop: ' + hasOwnProp(obj, 'prop'));
console.log('toString: ' + hasOwnProp(obj, 'toString'));
console.log('hasOwnProperty: ' + hasOwnProp(obj, 'hasOwnProperty'));

obj['hasOwnProperty'] = 1;

console.log('hasOwnProperty: ' + hasOwnProp(obj, 'hasOwnProperty'));

答案 2 :(得分:0)

任何内置都可以在JS中重写 - 它通常被认为是避免在可能的情况下覆盖任何本机方法的最佳实践。如果保留了原始功能,它就可以正常运行,因为它仍然会按预期运行,如果再次正确覆盖,甚至可以进一步扩展。

由于这被认为是最佳做法,我建议重新映射密钥以避免覆盖它们。如果重新映射密钥不是一个选项,那么你可以通过本地引用/包装Object.hasOwnPropertyObject.prototype.hasOwnProperty使它感觉不那么混乱。在hasOwnProperty的情况下,您可以实现迭代器(因为迭代可枚举的非继承属性是hasOwnProperty)方法的一种非常常见的用法,以降低其使用的可能性。对于不太熟悉你的对象试图直接迭代的风险总是存在,所以我真的觉得密钥映射是更安全的赌注,即使它确实导致服务器端密钥和本地密钥之间的细微差别。

键映射可以像使用hasOwnProperty_data而不是hasOwnProperty这样的后缀一样简单,这意味着对象会按预期运行,并且IDE的自动完成功能可能仍然足够接近知道该物业代表什么。

映射函数可能如下所示:



function remapKeys(myObj){
    for(var key in myObj){
      if(Object.prototype.hasOwnProperty.call(myObj, key)){      
        if((key in Object) && Object[key] !== myObj[key]){ // Check key is present on Object and that it's different ie an overridden property
          myObj[key + "_data"] = myObj[key]; 
          delete myObj[key]; // Remove the key   
        } 
      }
    }
    return myObj; // Alters the object directly so no need to return but safer
}

// Test
var a = {};
a.hasOwnProperty = function(){ return 'overridden'; };
a.otherProp = 'test';
remapKeys(a);
console.log(a); // a { hasOwnProperty_data : function(){ return 'overridden';}, otherProp: 'test' } 
console.log(a.hasOwnProperty('otherProp')); // true