检测对象中属性的存在与否可以通过几种方法来判断。
使用in关键字
如果指定的属性在指定的对象或其原型链中,则 in 运算符返回 true。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const car = { make: 'Honda', model: 'Accord', year: 1998 };
console.log('make' in car);
delete car.make;
console.log('make' in car);
if ('make' in car === false) { car.make = 'Suzuki'; }
console.log(car.make);
console.log('make' in car);
|
语法
prop in object
参数
- prop:一个字符串类型或者 symbol 类型的属性名或者数组索引(非 symbol 类型将会强制转为字符串)。
用法
下面的例子演示了一些 in 运算符的用法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); 0 in trees 3 in trees 6 in trees "bay" in trees
"length" in trees
Symbol.iterator in trees
"PI" in Math
var mycar = {make: "Honda", model: "Accord", year: 1998}; "make" in mycar "model" in mycar
|
in右操作数必须是一个对象值。例如,你可以指定使用String构造函数创建的字符串,但不能指定字符串文字。
1 2 3 4
| var color1 = new String("green"); "length" in color1 var color2 = "coral"; "length" in color2
|
对被删除或值为 undefined 的属性使用in
如果你使用 delete 运算符删除了一个属性,则 in 运算符对所删除属性返回 false。
1 2 3 4 5 6 7
| var mycar = {make: "Honda", model: "Accord", year: 1998}; delete mycar.make; "make" in mycar;
var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); delete trees[3]; 3 in trees;
|
如果你只是将一个属性的值赋值为undefined,而没有删除它,则 in 运算仍然会返回true。
1 2 3 4 5 6 7
| var mycar = {make: "Honda", model: "Accord", year: 1998}; mycar.make = undefined; "make" in mycar;
var trees = new Array("redwood", "bay", "cedar", "oak", "maple"); trees[3] = undefined; 3 in trees;
|
继承属性
如果一个属性是从原型链上继承来的,in 运算符也会返回 true。
使用对象的hasOwn()方法
如果指定的对象自身有指定的属性,则静态方法 Object.hasOwn() 返回 true。如果属性是继承的或者不存在,该方法返回 false。
备注: Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var o={x:1}; o.hasOwnProperty("x"); o.hasOwnProperty("y"); o.hasOwnProperty("toString");
const object1 = { prop: 'exists' };
console.log(Object.hasOwn(object1, 'prop'));
console.log(Object.hasOwn(object1, 'toString'));
console.log(Object.hasOwn(object1, 'undeclaredPropertyValue'));
|
语法
Object.hasOwn(obj, prop)
- obj:要测试的 JavaScript 实例对象。
- prop:要测试属性的 String 类型的名称或者 Symbol。
- 返回值:如果指定的对象中直接定义了指定的属性,则返回 true;否则返回 false。
建议使用此方法替代 Object.hasOwnProperty(),因为它适用于使用 Object.create(null) 创建的对象且重写了继承的 hasOwnProperty() 方法的对象。尽管可以通过在外部对象上调用 Object.prototype.hasOwnProperty() 解决这些问题,但是 Object.hasOwn() 更加直观。
用法
使用 hasOwn 去测试属性是否存在
以下代码展示了如何确定 example 对象中是否包含名为 prop 的属性。
1 2 3 4 5 6 7 8 9 10 11 12
| const example = {}; Object.hasOwn(example, 'prop');
example.prop = 'exists'; Object.hasOwn(example, 'prop');
example.prop = null; Object.hasOwn(example, 'prop');
example.prop = undefined; Object.hasOwn(example, 'prop');
|
直接属性和继承属性
const example = {};
example.prop = ‘exists’;
1 2 3 4 5 6 7 8 9 10 11
|
Object.hasOwn(example, 'prop'); Object.hasOwn(example, 'toString'); Object.hasOwn(example, 'hasOwnProperty');
'prop' in example; 'toString' in example; 'hasOwnProperty' in example;
|
迭代对象的属性
要迭代对象的可枚举属性,你应该这样使用:
1 2 3 4 5 6
| const example = { foo: true, bar: true }; for (const name of Object.keys(example)) { }
|
但是如果你使用 for…in,你应该使用 Object.hasOwn() 跳过继承属性:
1 2 3 4 5 6 7
| const example = { foo: true, bar: true }; for (const name in example) { if (Object.hasOwn(example, name)) { } }
|
检查数组索引是否存在
Array 中的元素被定义为直接属性,所以你可以使用 hasOwn() 方法去检查一个指定的索引是否存在:
1 2 3 4
| const fruits = ['Apple', 'Banana','Watermelon', 'Orange']; Object.hasOwn(fruits, 3); Object.hasOwn(fruits, 4);
|
hasOwnProperty 的问题案例
本部分证明了影响 hasOwnProperty 的问题对 hasOwn() 是免疫的。首先,它可以与重新实现的 hasOwnProperty() 一起使用:
1 2 3 4 5 6 7 8 9 10 11 12
| const foo = { hasOwnProperty() { return false; }, bar: 'The dragons be out of office', };
if (Object.hasOwn(foo, 'bar')) { console.log(foo.bar); }
|
它也可以用于测试使用 Object.create(null) 创建的对象。这些对象不会继承自 Object.prototype,因此 hasOwnProperty() 方法是无法访问的。
1 2 3 4 5 6 7
| const foo = Object.create(null); foo.prop = 'exists'; if (Object.hasOwn(foo, 'prop')) { console.log(foo.prop); }
|
用undefined判断
自有属性和继承属性均可判断。
1 2 3 4
| var o={x:1}; o.x!==undefined; o.y!==undefined; o.toString!==undefined
|
该方法存在一个问题,如果属性的值就是undefined的话,该方法不能返回想要的结果,如下
1 2 3 4
| var o={x:undefined}; o.x!==undefined; o.y!==undefined; o.toString!==undefined
|
在条件语句中直接判断
1 2 3 4
| var o={}; if(o.x) { o.x+=1; }
|