如果对象可以包含名为“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
为什么解决方案不应该是唯一推荐的方式?直接使用对象中的方法似乎是失败的方法,特别是如果它包含外部数据(不在一个人的控制中)
答案 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.hasOwnProperty
或Object.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