关于javascript:ObjecthasOwn-检查对象是否包含某一属性参数

9次阅读

共计 2533 个字符,预计需要花费 7 分钟才能阅读完成。

本文首发于我的集体 Blog,永恒地址:https://tie.pub/2021/11/objec…,
欢送大家订阅。

在过来咱们判断某个字符串变量是否是对象的自有属性时,通常应用 Object 对象原型链上的 hasOwnProperty 办法来判断:

const hasOwnProperty = Object.prototype.hasOwnProperty;

if (hasOwnProperty.call(object, 'foo')) {// `object` 蕴含属性 `foo`.}

既然 Object.prototype 蕴含 hasOwnProperty 办法,且能够判断属性参数,为什么继承 Object 属性的 object 不间接应用 object.hasOwnProperty 呢?答案是 JavaScript 一般对象的原型能够被笼罩,应用 Object.prototype.hasOwnProperty 能够确保安全正确。

const baz = {hasOwnProperty: function () {return false;},
  ba: 'own property',
};

能够看到 baz 对象领有从新定义的 hasOwnProperty 办法,该办法笼罩从 Object.prototype 继承的办法 hasOwnProperty,间接调用 baz.hasOwnProperty('ba') 只会返回 false。

另外 Object.create(null) 会创立一个空对象,该空对象没有继承 Object.prototype 对象,所以会报如下谬误:

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

Object.hasOwn 提案

当初 ECMAScript 官网正式提出 Object.hasOwn 提案,快捷判断对象自有属性,进步代码可读性。

if (Object.hasOwn(object, 'foo')) {// `object` 蕴含属性 `foo`.}

提案办法 Object.hasOwnObject.prototype.hasOwnProperty.call(object, property) 具备雷同的行为:

let object = {foo: false};
Object.hasOwn(object, 'foo'); // true

let object2 = Object.create({foo: true});
Object.hasOwn(object2, 'foo'); // false

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

let object4 = {foo: undefined, baz: null};
Object.hasOwn(object4, 'foo'); // true
Object.hasOwn(object4, 'baz'); // true

Object.hasOwn(example, 'toString'); // false
Object.hasOwn(example, 'hasOwnProperty'); // false

in 操作符

有时候咱们依据须要应用 in 操作符判断某参数是否是对象的属性:

let object = {foo: false};
if ('foo' in object) {// `foo` 是 `object` 的属性}

in 操作符与 Object.hasOwn 的不同在于除了判断对象的自有属性外,还会查看原型链上是否蕴含这一属性:

let object = {};
'toString' in object; // true
'hasOwnProperty' in object; // true
Object.hasOwn('toString'); //false

for ... in 循环

JavaScript 中能够应用 for in 循环遍历一个对象,因为 in 操作符会查看原型链。所以须要应用 Object.hasOwn 跳过继承属性:

let object = {foo: true, bar: true};
for (let name in object) {if (Object.hasOwn(object, name)) {// ...}
}

查看数组是否蕴含某一个索引

因为数组 Array 是一种非凡的对象,咱们也能够应用 Object.hasOwn 判断数组的索引:

let friends = ['吴文俊', '李星', '小郭', '浩哥', '小白龙'];
Object.hasOwn(friends, 2); // true - '小郭'
Object.hasOwn(friends, 5); // false

polyfill 反对

在不反对的浏览器中,咱们须要应用一些回退形式。咱们利用 Object.hasOwnObject.prototype.hasOwnProperty.call(object, property) 的雷同行为实现反对计划:

if (!Object.hasOwn) {
  Object.defineProperty(Object, 'hasOwn', {value: function (object, property) {if (object == null) {throw new TypeError('Cannot convert undefined or null to object');
      }
      return Object.prototype.hasOwnProperty.call(Object(object), property);
    },
    configurable: true,
    enumerable: false,
    writable: true,
  });
}

除此之外咱们在平时的开发过程中也会应用社区提供的工具库 has 和 lodash.has,它们都能很好地判断对象的属性。

浏览器反对状况

截至文章公布日 2021 年 11 月 9 日,浏览器对 Object.hasOwn 的反对状况如下:

  • Chrome 93+
  • Firefox 92+
  • Safari 不反对
  • Edge 93+

举荐浏览

  1. ES 提案:可选链 (optional chaining)
  2. String.prototype.replaceAll

正文完
 0