本文详细解析JavaScript中判断对象属性存在的5种方法,包括Reflect.has、in操作符、hasOwnProperty及其调用方式,以及ES2022新增的Object.hasOwn。重点分析各方法在处理原型链、null对象及属性名冲突时的差异,推荐在现代开发中优先使用Object.hasOwn以确保准确性。
前言
近期空闲下来,计划开展8月的持续写作活动。此前因工作繁忙未能保持连续更新,如今时间充裕,便继续分享技术内容。本次主题聚焦于提升js开发效率的实用技巧。
在业务代码开发中,判断对象是否包含特定属性是高频操作。无论此前掌握多少种判断手段,阅读完本文后,你将至少掌握5种有效方法,从而在实际工作中更加从容应对各类场景。
下面直接展示判断对象是否具有属性的5种具体方法,请继续阅读后续内容。
5种方法
1. Reflect.has()方法
Reflect.has()方法用于检测对象中是否存在指定属性。
具体用法如下:
Reflect.has({x: 0}, "x"); // true
Reflect.has({x: 0}, "y"); // false执行结果如下:

需要注意的是,若属性存在于原型链中,该方法同样会返回true。
示例如下:
Reflect.has({x: 0}, "toString");执行结果如下:

2. in操作符
in运算符用于检查对象是否包含某个属性,若包含则返回true,否则返回false。其功能与Reflect.has()方法一致。
const obj = {p: 1};
'p' in obj; // true
'toString' in obj; // true执行结果如下:

由此可见,in操作符与Reflect.has()方法存在共同局限:当属性源自对象原型时,它们均会返回true。如何解决此问题?请继续阅读下文。
3. Object.prototype.hasOwnProperty()方法
针对in操作符和Reflect.has()方法上述局限,可使用对象的hasOwnProperty()方法进行判断,以确认'toString'是否为对象自身的属性。
示例如下:
const obj = {p: 1};
console.log(obj.hasOwnProperty('toString')); // false 执行结果如下:

hasOwnProperty()方法返回布尔值,指示对象是否具有指定属性(非继承属性)。它能正确区分对象自身属性与原型属性。
然而,该方法仍存在缺陷:若对象通过Object.create(null)方式创建,则无法使用hasOwnProperty()方法进行判断。
示例如下:
var obj = Object.create(null);
obj.p = 1;
obj.hasOwnProperty('p'); // 报错执行结果如下:

此外,若将hasOwnProperty()作为对象的一个属性,同样无法使用hasOwnProperty()方法判断属性是否来自原型链。示例如下:
var obj = {
p: 1,
hasOwnProperty: function () {
return false;
}
}
obj.hasOwnProperty('p'); // 始终返回false执行结果如下:

造成该问题的原因是,javascript未将hasOwnProperty设为敏感词,因此可为对象声明一个hasOwnProperty属性,从而导致上述判断失效。
如何解决此问题?请继续阅读下文。
4. Object.prototype.hasOwnProperty.call()方法
为解决上述问题,需使用原型链上真正的hasOwnProperty方法。
示例如下:

即使用Object.prototype.hasOwnPerporty.call()方法可解决上述问题,也可采用以下写法。示例如下:
Object.prototype.hasOwnPerporty.call(obj, 'p'); // true
或
({}).hasOwnProperty.call(obj, 'p'); // true5. Object.hasOwn()方法
Object.hasOwn()方法是ES2022新提出的,旨在替代Object.prototype.hasOwnProperty()。根据MDN文档说明:若指定对象具有作为其自身属性的指定属性,则hasOwn()方法返回true;若该属性为继承属性或不存在,则返回false。
使用方法如下:
const object1 = {prop: 'exists'};
console.log(Object.hasOwn(object1, 'prop')); // true
console.log(Object.hasOwn(object1, 'toString'));// false其他示例如下:
const example = {};
Object.hasOwn(example, 'prop'); // false - 'prop' has not been defined
example.prop = 'exists';
Object.hasOwn(example, 'prop'); // true - 'prop' has been defined
example.prop = null;
Object.hasOwn(example, 'prop'); // true - own property exists with value of null
example.prop = undefined;
Object.hasOwn(example, 'prop'); // true - own property exists with value of undefinedObject.hasOwn()与Object.hasOwnPeoperty()的区别在于:实例的hasOwnProperty方法是从Object的原型上获取的,若使用Object.create(null)方式创建对象,则无法获取hasOwnProperty方法;而hasOwn作为Object的静态方法,可直接通过Object调用。
示例如下:
const obj1 = Object.create(null);
obj1.name = '111';
console.log(obj1.hasOwnProperty('name')); // 报错
const obj2 = Object.create(null);
obj2.name = '222';
console.log(Object.hasOwn(obj2, 'name')); // true
const obj3 = {
p: 1,
hasOwnProperty: function () {
return false
}
}
console.log(Object.hasOwn(obj3, 'p')); // true从上述代码结果可见,Object.hasOwn()方法可解决前述所有问题。但因其为ES2022提出,还需考察其兼容性。
兼容性示例如下:

可见,浏览器对其支持情况良好,开发者可放心使用。
至此,关于JavaScript中判断对象是否具有属性的5种方法分享完毕。如需了解更多JavaScript判断对象方法,请搜索本站往期文章或继续阅读相关文章。感谢大家的支持!