ECMAScript建议。Accessible Object.prototype.hasOwnProperty()

79 阅读3分钟

在这篇博文中,我们研究了ECMAScript提案 "AccessibleObject.prototype.hasOwnProperty()"(作者Jamie Kyle和Tierney Cyren)。它提出了一种新的、更简单的方法来检查一个对象是否有自己的(非继承的)属性。


目录。


检查一个对象是否有自己的属性

在本节中,我们看看现有的检查对象是否有自己的属性的方法。它们中的每一个都有缺点,这就是为什么需要Object.hasOwn()

in 操作符并不总是我们想要的东西

in 操作符检查一个对象是否有一个具有给定名称的属性。

> 'name' in {name: 'Jane'}
true
> 'name' in {}
false

然而,如果我们把对象当作字典,那么我们想忽略继承的属性(而in 考虑了它们)。例如,被解释为一个字典,下面的对象应该是空的,但是in 说它有属性'toString'

> 'toString' in {}
true

这是因为{}Object.prototype 继承了方法.toString()

> Object.getPrototypeOf({}) === Object.prototype
true

.hasOwnProperty() 是不安全的

所有通过对象字面创建的对象都从Object.prototype 继承了方法.hasOwnProperty() 。该方法似乎可以做我们想要的事情。

> {name: 'Jane'}.hasOwnProperty('name')
true
> {}.hasOwnProperty('name')
false
> {}.hasOwnProperty('toString')
false

然而,.hasOwnProperty() 在两种情况下失败。

首先,我们可以创建不继承自Object.prototype ,也没有那个方法的对象。

> Object.create(null).hasOwnProperty('name')
TypeError: Object.create(...).hasOwnProperty is not a function

第二,如果一个对象有一个名称为'hasOwnProperty' 的自己的属性,那么这个属性就会覆盖Object.prototype.hasOwnProperty ,我们就不能访问它。

> {hasOwnProperty: 'yes'}.hasOwnProperty('name')
TypeError: {(intermediate value)}.hasOwnProperty is not a function

直接访问Object.prototype.hasOwnProperty()

为了解决我们在上一节遇到的问题,我们需要直接访问Object.prototype.hasOwnProperty()

function hasProp(obj, propName) {
  return Object.prototype.hasOwnProperty.call(obj, propName);
}
assert.equal(
  hasProp(Object.create(null), 'name'), false);
assert.equal(
  hasProp({hasOwnProperty: 'yes'}, 'name'), false);

hasProp() 工作方式与 完全一样。Object.hasOwn()

建议:Object.hasOwn()

新的建议完全按照我们想要的方式工作。

> Object.hasOwn({name: 'Jane'}, 'name')
true
> Object.hasOwn({}, 'name')
false
> Object.hasOwn({}, 'toString')
false
> Object.hasOwn(Object.create(null), 'name')
false
> Object.hasOwn({hasOwnProperty: 'yes'}, 'name')
false
> Object.hasOwn({hasOwn: 'yes'}, 'name')
false

关于使用对象作为字典的警告

一般来说,对象不是好的字典。有几个我们必须要面对的陷阱

相反,地图是很好的字典,没有陷阱。

关于Object.hasOwn() 的常见问题

Object.hasOwnProperty() 不是一个更好的名字吗?

唉,这个名字已经不能用了。

> 'hasOwnProperty' in Object
true

为什么?Object 是一个函数,它是一个对象。

> const proto = Object.getPrototypeOf.bind(Object);
> proto(Object) === Function.prototype
true
> proto(proto(Object)) === Object.prototype
true

Object.hasOwn() 的可用性

关于JavaScript中面向对象编程的更多信息

"JavaScript for impatient programmers "一书中的材料。