曾经对 hasOwnProperty() 方法和 in 操作符感到困惑,这回看书看到,就在这里再次归纳总结一下
-----------------------------------------------------------------------------------------
hasOwnProperty 和 in 都是用于检测 “对象是否包含某个属性(包括一般属性和方法,java里叫做对象成员)” :
对象.hasOwnProperty("属性名称"); // "属性名称" 以字符串形式传递
"属性名称" in 对象; // 用法同上
某些情况下,两者效果一致,可以混用:
// 创建一个自定义对象 var obj_1 = { // 对象定义了自己的属性 sayHi: function() { return "Hi~ I‘m an object"; } } obj_1.hasOwnProperty("sayHi"); // 返回 true "sayHi" in obj_1; // 返回 true
都返回 true。
但如果换种使用情况:
// 还是自定义对象 var obj_2 = { // 也定义了自己的方法 sayHi: function() { return "Hi~ I‘m another object"; } } obj_2.hasOwnProperty("toString"); // 返回 false "toString" in obj_2; // 返回 true
hsaOwnProperty 方法的返回结果跟上面不一样了。。
稍微对比前后两次使用情况,我们就可以发现其中的差别:
前一个 hasOwnProperty 检测的是 sayHi 方法,由对象自己定义,结果返回 true。
后一个 hasOwnProperty 检测的是 toString 方法,来自父类,结果返回 false。
产生什么结果是跟属性的来源有关么? 不是:
// 又是自定义对象 var obj_3 = { // 并且重写了 toString 方法 toString: function() { return "This is function \"toString\" which overridden by obj_3"; } } obj_3.hasOwnProperty("toString"); // 返回 true "toString" in obj_3; // 返回 true
这个 toString 仍是来源于父类,不同的是它经过了重写,然后结果也跟着不一样了。
“重写”在这其中起了什么作用?
如果要用一个词概括的话那应该是“专属”:
被重写的属性只属于重写了它的对象,这个对象独自拥有了这个属性(的拷贝),使用时无需再从父类身上寻找和获取。而被重写的属性也打上了专属于这个对象的印记,这个属性无法被别的对象(用hasOwnProperty)检测为true。
因此 如果按照字面意思,将 对象.hasOwnProperty("xx") 理解成:“对象是否拥有xx属性” 显然是不够准确的——根类的属性为所有对象所共有,却无法检测为true。
更准确的说法应该是:“xx属性是否为指定对象所独有” 。
那 in 呢?
从上面的结果看,in 总是返回 true ——不管“公有”、“私有”,不管是自己的还是父类的。
只要 hasOwnProperty 为 true,in 必为 true。in 的判定范围大于 hasOwnProperty 的判定范围。
如果把 hasOwnProperty 理解为“专属”,那 in 就是 专属+父类(或者说原型链),范围是“一个体系”。
所以 "xx" in 对象 可以理解成:“xx属性是否存在于指定对象所代表的体系里”。
总结:
hasOwnProperty 用于检测 某个属性是否指定对象的专属属性。
in 用于检测 某个属性是否存在于对象或它的原型链中。
hasOwnProperty 和 in,布布扣,bubuko.com