hasOwnProperty 和 in

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

 

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

首先要知道, 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 方法不再返回 true。

稍微对比前后两次使用情况,我们就可以发现其中的差别:

  前一个 hasOwnProperty 检测的是 sayHi 方法,由对象自己定义,结果返回 true。

  后一个 hasOwnProperty 检测的是 toString 方法,来自基类(Object),结果返回 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 仍是来源于基类,只是它重写。而我们知道, 重写会在实例上新建一个属性。

 

书上看到的解释大概是这样:

  每当程序需要读取某个对象的某个属性时, 解析器都会进行搜索。 搜索首先会从对象实例本身开始, 如果找到, 则返回该属性的值; 如果找不到, 则往上(父类原型)继续搜索, 直至最顶层的基类(原型)。如果搜遍整个原型链都找不到, 则返回 undefined。

使用 hasOwnProperty 方法时,搜索只会在对象实例上进行, 找不到就直接返回 false。

而执行 in 时,解析器的搜索不再限于对象实例, 只有在搜遍整个原型链都找不到的时候才会返回 false。

这就是两者的差别。

 

总结一下:

hasOwnProperty 用以检测“对象是否拥有某个属性”, 这个属性可以由对象自身定义,也可以由继承的属性重写而来。

in 操作符用以检测“某个属性是否对对象可用”, 这个属性可以是对象自身定义所得, 也可以是来自于继承, 无需重写。

posted @ 2014-08-09 01:21  Huang.S  阅读(306)  评论(0编辑  收藏  举报