Object.hasOwn()

如果指定的对象 自身 有指定的属性,则静态方法 Object.hasOwn() 返回 true 。如果属性是继承的或者不存在,该方法返回 false

备注: Object.hasOwn() 旨在取代 Object.hasOwnProperty()

尝试一下

语法

hasOwn(instance, prop)
Copy to Clipboard

参数

instance

要测试的 JavaScript 实例对象。

prop

要测试属性的 String 类型的名称或者 Symbol。

返回值

如果指定的对象中直接定义了指定的属性,则返回 true ;否则返回 false

描述

如果指定的属性是该对象的直接属性—— Object.hasOwn() 方法返回 true ,即使属性值是 null undefined 。如果属性是继承的或者不存在,该方法返回 false 。它不像 in 运算符,这个方法不检查对象的原型链中的指定属性。

建议使用此方法替代 Object.hasOwnProperty() ,因为它适用于使用 Object.create(null) 创建的对象以及覆盖了继承的 hasOwnProperty() 方法的对象。尽管可以通过在外部对象上调用 Object.prototype.hasOwnProperty() 解决这些问题,但是 Object.hasOwn() 更加直观。

示例

使用 hasOwn 去测试属性是否存在

以下编码展示了如何确定 example 对象中是否包含名为 prop 的属性。

const example = {};
Object.hasOwn(example, 'prop');   // false - 'prop' has not been defined

example.prop = 'exists';
Object.hasOwn(example, 'prop');   // true - 'prop' has been defined

example.prop = null;
Object.hasOwn(example, 'prop');   // true - own property exists with value of null

example.prop = undefined;
Object.hasOwn(example, 'prop');   // true - own property exists with value of undefined
Copy to Clipboard

直接属性和继承属性

以下示例区分了直接属性和通过原型链继承的属性:

const example = {};
example.prop = 'exists';

// `hasOwn` will only return true for direct properties:
Object.hasOwn(example, 'prop');             // returns true
Object.hasOwn(example, 'toString');         // returns false
Object.hasOwn(example, 'hasOwnProperty');   // returns false

// The `in` operator will return true for direct or inherited properties:
'prop' in example;                          // returns true
'toString' in example;                      // returns true
'hasOwnProperty' in example;                // returns true
Copy to Clipboard

迭代对象的属性

要迭代对象的可枚举属性,你 应该 这样使用:

const example = { foo: true, bar: true };
for (const name of Object.keys(example)) {
  // …
}
Copy to Clipboard

但是如果你使用 for...in ,你应该使用 Object.hasOwn() 跳过继承属性:

const example = { foo: true, bar: true };
for (const name in example) {
  if (Object.hasOwn(example, name)) {
    // …
  }
}
Copy to Clipboard

检查数组索引是否存在

Array 中的元素被定义为直接属性,所以你可以使用 hasOwn() 方法去检查一个指定的索引是否存在:

const fruits = ['Apple', 'Banana','Watermelon', 'Orange'];
Object.hasOwn(fruits, 3);   // true ('Orange')
Object.hasOwn(fruits, 4);   // false - not defined
Copy to Clipboard

hasOwnProperty 的问题案例

本部分证明了影响 hasOwnProperty 的问题对 hasOwn() 是免疫的。首先,它可以与重新实现的 hasOwnProperty() 一起使用:

const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: 'The dragons be out of office',
};

if (Object.hasOwn(foo, 'bar')) {
  console.log(foo.bar); //true - reimplementation of hasOwnProperty() does not affect Object
}
Copy to Clipboard

它也可以用于测试使用 Object.create(null) 创建的对象。这些都不继承自 Object.prototype ,因此 hasOwnProperty() 无法访问。

const foo = Object.create(null);
foo.prop = 'exists';
if (Object.hasOwn(foo, 'prop')) {
  console.log(foo.prop); //true - works irrespective of how the object is created.
}