Object.hasOwn 替换掉 Object.prototype.hasOwnProperty

1,295 阅读2分钟

Object.hasOwn 替换掉 Object.prototype.hasOwnProperty

2021 年 6 月 25 日发布 · 标记为ECMAScript

建议使用 Object.hasOwn() 方法,因为它使得 Object.prototype.hasOwnProperty() 更易于使用。

阶段

目前这个提案还在第三阶段

Object.hasOwn提案为什么会出现呢?

目前,这样的代码是很常见:

const hasOwnProperty = Object.prototype.hasOwnProperty;

if (hasOwnProperty.call(object'foo')) {
  // `object` has property `foo`.
}

或者有些库使得使用 Object.prototype.hasOwnProperty 更简单:
npm: has
npm: lodash.has
See Related

使用 Object.hasOwn 这个新函数,我们可以将上边代码简写为:

if (Object.hasOwn(object'foo')) {
  // `object` has property `foo`.
}

在日常开发中,有某些常见的用法,使得 Object.prototype 上的方法有时可能不可用或是会被重新定义了。

比如:

1. Object.create(null):

Object.create(null) 会创建一个不从 Object.prototype 继承的对象,这使得Object.prototype 上的方法无法访问。

Object.create(null).hasOwnProperty("foo")
// Uncaught TypeError: Object.create(...).hasOwnProperty is not a function

2. 重新定义 hasOwnProperty:

如果你对对象的内置属性进行了重新赋值改写,那么你在调用某个属性(比如:.hasOwnProperty)时,肯定调用的不是对象的内置属性

let object = {
  hasOwnProperty() {
    throw new Error("gotcha!")
  }
}

object.hasOwnProperty("foo")
// Uncaught Error: gotcha!

3. ESLint no-prototype-builtins

在ESLint的规则 built-in rule 中,是禁止直接使用 Object.prototypes 内置函数

ESLint 文档中关于 no-prototype-builtins 说明:

对这一规则的错误例子:

/*eslint no-prototype-builtins: "error"*/
var hasBarProperty = foo.hasOwnProperty("bar");
...

对这一规则的正确例子:

/*eslint no-prototype-builtins: "error"*/
var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
...

提案

该提案添加了一个 Object.hasOwn(object, property) 方法,其行为与调用 hasOwnProperty.call(object, property) 相同

let object = { foofalse }
Object.hasOwn(object"foo"// true

let object2 = Object.create({ footrue })
Object.hasOwn(object2, "foo"// false

let object3 = Object.create(null)
Object.hasOwn(object3, "foo"// false

为什么不是 使用 Object.hasOwnProperty(object, property)?

Object.hasOwnProperty(property) 今天已经存在,因为 Object 本身继承自 Object.prototype,所以定义一个具有不同名称的新方法将是一个比较明显的变化。

为什么命名为 hasOwn 呢?

See Issue #3

Object.hasOwn 已经在 V8 v9.3 中,执行时在后边加上 --harmony-object-has-own 的标志就可以使用,Chrome 中不久之后也会推出它。

参考

社交信息 / Social Links