[JS回顾] 对象属性属于自身 or 原型链检测

303 阅读1分钟

目录

  1. prop in obj
  2. Object.prototype.hasOwnProperty.call(myObj,prop) 判断属性是否来自原型链
  3. Reflect.has 检测属性包含原型链上的属性

prop in obj

var o = {a:1,b:2};
'a' in o
// true

Object.prototype.hasOwnProperty.call() 判断属性是否来自原型链

JS 中Object对象原型上的*hasOwnProperty() 用来判断一个属性是定义在对象本身而不是继承自原型链

因为JS没有将 hasOwnProperty 作为一个 敏感词,所以我们很有可能将对象的一个属性命名为hasOwnProperty,这样一来就无法再使用对象原型的 hasOwnProperty 方法来判断属性是否是来自原型链。


o.hasOwnProperty('a'); // true
o.hasOwnProperty('valueOf'); // false

1) Object.prototype.hasOwnProperty.call

var o = {
  a: 1,
};

// 旧写法
'a' in o // true

Object.prototype.hasOwnProperty.call(o,'toString'); // false

Object.prototype.hasOwnProperty.call(o,'a'); // true

2) ({}).hasOwnProperty.call

({}).hasOwnProperty.call(o,'a'); // true
({}).hasOwnProperty.call(o,'valueOf'); // false

Reflect.has 检测属性包含原型链上的属性

Reflect.has方法对应name in obj里面的in运算符。

var o = {
  a: 1,
};

// 旧写法
'a' in o // true

// 新写法
Reflect.has(o, 'a') // true
Reflect.has(o, 'toString') // true

三 直接使用 hasOwnProperty 错误的2个场景

为什么使用 Object.prototype.hasOwnProperty.call(myObj1, prop) 而不是 myObj1.hasOwnProperty(prop)呢?

1) hasOwnProperty被改写

var o1 = {
    hasOwnProperty: function() {
        return 111;
    },
    b: '222'
};
 
o1.hasOwnProperty('b'); // 始终返回 111

1) Object.create(null)

如果使用 Object.create(null) 创建的对象是没有prototype的,这种情况下,调用上述方法只会得到 undefined。所以,使用 Object.prototype.hasOwnProperty.call(myObj, prop),可以确保调用到正确的方法,得到正确的结果。

var o1 = Object.create(null);
o1.hasOwnProperty('toString');
//  Uncaught TypeError: o1.hasOwnProperty is not a function

var o2 = {};
o2.hasOwnProperty('toString');
// false

参考

总结

  • prop in obj
  • Object.prototype.hasOwnProperty.call(myObj,prop) 判断属性是否来自原型链
  • Reflect.has 检测属性包含原型链上的属性