首页 > 代码库 > hasOwnProperty 和 in

hasOwnProperty 和 in

曾经对 hasOwnProperty() 方法和 in 操作符感到困惑,这回看书看到,就在这里再次归纳总结一下

 

-----------------------------------------------------------------------------------------

hasOwnPropertyin 都是用于检测 “对象是否包含某个属性(包括一般属性和方法,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 用于检测 某个属性是否存在于对象或它的原型链中。