JavaScript 系列 - Object.hasOwn 和 Object.prototype.hasOwnProperty

1,212 阅读2分钟

Object.hasOwn()

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

  • 不检查对象的原型链中的指定属性
  • 替代 Object.hasOwnProperty(),因为它适用于使用 Object.create(null) 创建的对象且重写了继承的 hasOwnProperty() 方法的对象。

直接属性和继承属性

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

// `hasOwn` 静态方法只会对目标对象的直接属性返回 true:
Object.hasOwn(example, 'prop');             // 返回 true
Object.hasOwn(example, 'toString');         // 返回 false
Object.hasOwn(example, 'hasOwnProperty');   // 返回 false

// `in` 运算符对目标对象的直接属性或继承属性均会返回 true:
'prop' in example;                          // 返回 true
'toString' in example;                      // 返回 true
'hasOwnProperty' in example;                // 返回 true

迭代对象的属性

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

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

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

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

检查数组索引是否存在

const fruits = ['Apple', 'Banana','Watermelon', 'Orange'];
Object.hasOwn(fruits, 3);   // true ('Orange')
Object.hasOwn(fruits, 4);   // false —— 没有定义的

hasOwnProperty 问题

  • 可以与重新实现的 hasOwnProperty() 一起使用
const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: 'The dragons be out of office',
};

if (Object.hasOwn(foo, 'bar')) {
  console.log(foo.bar); //true——重新实现 hasOwnProperty() 不会影响 Object
}
  • 可以用于 Object.create(null) 创建的对象
const foo = Object.create(null);
foo.prop = 'exists';
if (Object.hasOwn(foo, 'prop')) {
  console.log(foo.prop); // true —— 无论对象是如何创建的,它都可以运行。
}

Object.prototype.hasOwnProperty()

hasOwnProperty(prop)  方法返回一个布尔值,表示对象自有属性(而不是继承来的属性)中是否具有指定的属性。

  • 使用 hasOwnProperty 作为属性名称
const foo = {
  hasOwnProperty() {
    return false;
  },
  bar: "Here be dragons",
};

foo.hasOwnProperty("bar"); // 该重新实现始终返回 false
const foo = { bar: "Here be dragons" };

// 使用 Object.hasOwn() 方法——推荐
Object.hasOwn(foo, "bar"); // 返回 true

// 使用 Object 原型中的 hasOwnProperty 属性
Object.prototype.hasOwnProperty.call(foo, "bar"); // 返回 true

// 使用另一个 Object 的 hasOwnProperty,并在“this”设置为 foo 的情况下调用它
({}).hasOwnProperty.call(foo, "bar"); // 返回 true
  • 由 Object.create(null) 创建的对象
const foo = Object.create(null);
foo.prop = "exists";
foo.hasOwnProperty("prop"); // Uncaught TypeError: foo.hasOwnProperty is not a function