JavaScript 中 obj.hasOwnProperty(prop) 方法

语法

obj.hasOwnProperty(prop)

参数

prop

要检测的属性的 String 字符串形式表示的名称,或者 Symbol

返回值

用来判断某个对象是否含有指定的属性的布尔值 Boolean

描述

所有继承了 Object 的对象都会继承到 hasOwnProperty 方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

备注

即使属性的值是 null 或 undefined,只要属性存在,hasOwnProperty 依旧会返回 true

o = new Object();
o.propOne = null;
o.hasOwnProperty('propOne'); // 返回 true
o.propTwo = undefined;
o.hasOwnProperty('propTwo'); // 返回 true

示例

使用 hasOwnProperty 方法判断属性是否存在

下面的例子检测了对象 o 是否含有自身属性 prop

o = new Object();
o.hasOwnProperty('prop'); // 返回 false
o.prop = 'exists';
o.hasOwnProperty('prop'); // 返回 true
delete o.prop;
o.hasOwnProperty('prop'); // 返回 false

自身属性与继承属性

下面的例子演示了 hasOwnProperty 方法对待自身属性和继承属性的区别:

o = new Object();
o.prop = 'exists';
o.hasOwnProperty('prop');             // 返回 true
o.hasOwnProperty('toString');         // 返回 false
o.hasOwnProperty('hasOwnProperty');   // 返回 false

遍历一个对象的所有自身属性

下面的例子演示了如何在遍历一个对象的所有属性时忽略掉继承属性,注意这里 for...in  循环只会遍历可枚举属性,所以不应该基于这个循环中没有不可枚举的属性而得出 hasOwnProperty 是严格限制于可枚举项目的(如同 Object.getOwnPropertyNames())。

var buz = {
  fog: 'stack'
};

for (var name in buz) {
  if (buz.hasOwnProperty(name)) {
    console.log('this is fog (' +
      name + ') for sure. Value: ' + buz[name]);
  }
  else {
    console.log(name); // toString or something else
  }
}

使用 hasOwnProperty 作为属性名

JavaScript 并没有保护 hasOwnProperty 这个属性名,因此,当某个对象可能自有一个占用该属性名的属性时,就需要使用外部的 hasOwnProperty 获得正确的结果:

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'Here be dragons'
};

foo.hasOwnProperty('bar'); // 始终返回 false

// 如果担心这种情况,
// 可以直接使用原型链上真正的 hasOwnProperty 方法
({}).hasOwnProperty.call(foo, 'bar'); // true

// 也可以使用 Object 原型上的 hasOwnProperty 属性
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

注意,只有在最后一种情况下,才不会新建任何对象。

直接上代码来个示例:

function ObjWithProto(){
    this.foo = 'foo_val'
}
ObjWithProto.prototype.bar = 'bar_val'
var dict = new ObjWithProto()
dict.foobar = 'foobar_val'

dict.hasOwnProperty('foo') // true
dict.hasOwnProperty('foobar') // true
dict.hasOwnProperty('bar') // false

再来看 for…in , 遍历一个对象的可枚举属性

for(let i in dict){
    console.log(i)
}
//foo
// foobar
// bar        //原型链上的bar也获取到了

为了遍历一个对象的所有属性时忽略掉继承属性,使用hasOwnProperty()来过滤该对象上的继承属性。

for(let i in dict){
    if(dict.hasOwnProperty(i)){
       console.log(i)
    }
}
//foo
//foobar

再来看看原型连上的一个继承

    function ObjWithProto(){
        this.foo = 'foo_val'
    }
    ObjWithProto.prototype.bar = 'bar_val'

    function Person(){
        this.name = 'Person_name'
    }
    Person.prototype = new ObjWithProto()
    var _child = new Person()

    for(let i in _child){
        console.log(i)
    }

    console.log('------ this is a line -------')

    for(let i in _child){
        if(_child.hasOwnProperty(i)){
            console.log(i)
        }
    }
    _child.hasOwnProperty('name') // true
    _child.hasOwnProperty('foo') // false
    _child.hasOwnProperty('bar') // false

    //name
    //foo
    //bar
    //------ this is a line -------
    //name

用for...in循环会获取到原型链上的可枚举属性,不过可以使用hasOwnProperty()方法过滤掉。

上一篇:关于js一般对象与标配对象


下一篇:如何在 MacBook Pro 上通过 Touch Bar 使用 VoiceOver ?