共计 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.hasOwn
与 Object.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.hasOwn
与 Object.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+
举荐浏览
- ES 提案:可选链 (optional chaining)
- String.prototype.replaceAll