Javascript 使用hasOwnProperty的合适/推荐方式是什么?
假设对象可能包含名为“hasOwnProperty”的自有属性: 如果您考虑Object.keys()、Object.assign()等,这会起作用,界面有点难看。。那么,有没有更好的办法Javascript 使用hasOwnProperty的合适/推荐方式是什么?,javascript,Javascript,假设对象可能包含名为“hasOwnProperty”的自有属性: 如果您考虑Object.keys()、Object.assign()等,这会起作用,界面有点难看。。那么,有没有更好的办法 > Object.hasOwnProperty.call(a, "abc"); true > Object.hasOwnProperty.call(a, "hasOwnProperty"); true 为什么解决方案不是唯一推荐的方法?直接使用对象中的方法似乎会导致失败,特别是当对象包含外部数据
> Object.hasOwnProperty.call(a, "abc");
true
> Object.hasOwnProperty.call(a, "hasOwnProperty");
true
为什么解决方案不是唯一推荐的方法?直接使用对象中的方法似乎会导致失败,特别是当对象包含外部数据(不在自己的控制范围内)时。使用hasOwnProperty的适当/推荐方法是作为过滤器,或确定对象是否。。。嗯,他有那个财产。它们只是您在第二个命令中使用它的方式
a.hasOwnProperty('abc')
通过使用a['hasOwnProperty']=1
覆盖对象hasOwnProperty
,在安全有效的情况下,只会删除在该对象上使用hasOwnProperty函数的功能
我错过了你真正的问题吗?看起来你已经从你的例子中知道了这一点
借
“直接从对象使用方法似乎是失败的秘诀
你指的是这样的东西吗:
> dog = {speak: function() {console.log('ruff! ruff!')}};
> dog.speak(); // ruff! ruff!
因为正如您所能想象的那样,这在很多方面都非常有用。如果您可以使用ECMAScript 2015,您可以尝试一下。 如果对象上存在给定属性,则返回该属性的属性描述符,否则未定义 为了简化,您可以创建此函数:
var hasOwnProp = (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop) !== undefined;
var obj=新对象();
obj.prop='存在';
console.log('使用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)!=未定义;
console.log('使用getOwnPropertyDescriptor')
log('prop:'+hasOwnProp(obj,'prop'));
log('toString:'+hasOwnProp(obj,'toString'));
log('hasOwnProperty:'+hasOwnProp(obj,'hasOwnProperty');
obj['hasOwnProperty']=1;
log('hasOwnProperty:'+hasOwnProp(obj,'hasOwnProperty')代码>任何内置方法都可以在JS中重写-通常认为最好避免在可能的情况下重写任何本机方法。如果保留了原始功能,它就可以了,因为它仍将按预期运行,如果再次正确覆盖,甚至可能进一步扩展
由于这被认为是最佳实践,我建议重新映射键以避免覆盖它们。如果不选择重新映射键,则可以通过本地引用/包装Object.hasOwnProperty
或Object.prototype.hasOwnProperty
使其感觉不那么凌乱。在hasOwnProperty
的情况下,您可以实现一个迭代器(因为迭代可枚举的非继承属性是hasOwnProperty
方法的一个非常常见的用法),以减少使用它的可能性。总有不太熟悉您的对象的人尝试直接迭代的风险,所以我真的觉得密钥映射是更安全的选择,即使它确实会导致服务器端密钥和本地密钥之间的细微差异
键映射可以像使用后缀一样简单,使用hasOwnProperty\u data
而不是hasOwnProperty
,这意味着对象的行为将符合预期,并且IDE的自动完成可能仍然足够接近,可以知道该属性表示什么
映射函数可能如下所示:
函数remapKeys(myObj){
for(myObj中的var键){
if(Object.prototype.hasOwnProperty.call(myObj,key)){
如果((对象中的键)&&Object[key]!==myObj[key]){//检查对象上是否存在键,并且它是不同的属性,即被重写的属性
myObj[key+“_data”]=myObj[key];
删除myObj[key];//删除该键
}
}
}
return myObj;//直接更改对象,因此无需返回,但更安全
}
//试验
变量a={};
a、 hasOwnProperty=function(){return'overrided';};
a、 otherProp=‘测试’;
雷马普凯斯(a);
console.log(a);//a{hasOwnProperty_data:function(){return'overrided';},otherProp:'test'}
console.log(a.hasOwnProperty('otherProp'));//true
可能会有帮助:我指的是将数据(如文档标记化)加载到对象中。文档可能是关于javascript的,并且可能包含标记“hasOwnProperty”。当然,将对象与方法结合使用是很强大的,但这不是我的问题。为了避免覆盖内置方法,这似乎需要很大的开销(内存和代码)。我更愿意确保它在Object.create(null)
中没有任何方法。您只需要前11行,并且在加载数据后只运行一次。这将是最小的内存占用它修改对象的地方,不克隆它等。我认为这是一个小的价格支付访问内置和避免混淆。我认为我的示例没有处理的唯一考虑事项是嵌套对象——将其重构为使用递归将处理这些问题。第二个原因是拥有“自定义映射”可能会比仅仅添加后缀更有益。使用空原型创建对象可能与重写内置对象一样容易混淆。感谢您指出Reflect.getOwnPropertyDescriptor()
。在哪些方面它比Object.hasOwnProperty.call(obj,prop)
更好?
var hasOwnProp = (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop) !== undefined;