如何判断一个对象是否有给定的 Property
by aaronchenwei
两个感叹号(!!)
在 js 当中!!可以把类型转换成Boolean类型的值。
If it was falsey (e.g. 0, null, undefined, etc.), it will be false, otherwise, true.
上段代码说明一下!!的结果。
const a = 0;
console.log(!!a); // false
const b = true;
console.log(!!b); // true;
const c = false;
console.log(!!c); // false
const d = [];
console.log(!!d); // true
const e = null;
console.log(!!e); // false
const f = undefined;
console.log(!!f); // false
也许我们可以用!!来判断一个对象是否有给定的 Property。
const demoObject = {
name: "demo",
cool: false,
};
console.log(!!demoObject.name); // true (correct result as it's a truthy value)
console.log(!!demoObject.name2); // false
console.log(!!demoObject.cool); // false !!! (not as we expected)
可是这个方法最大的问题是!!会检查prototype链中是否有同名的 Property 存在。如果对象中的 Property 的名字和 prototype 中的一样,这个方法就无法判断了。
// Object.prototype.toString
console.log(!!demoObject.toString); // true
// !!Array.prototype.forEach
console.log(!![]["forEach"]); // true
总结:!!在判断一个对象是否有给定的 Property 上面并不太靠谱。
hasOwnProperty
Object.prototype.hasOwnProperty()可以用来检查一个对象是否有给定的 Property。
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object’s prototype chain.
const demoObject = {
name: "Hasky",
favouriteFood: null,
};
if (demoObject.hasOwnProperty("favouriteFood")) {
// true
// do something if it exists
}
这个方法也有一个问题。JavaScript 并不保护 Property 的名字。如果对象也有一个 Property 取名叫 hasOwnProperty,这个方法就有一个小问题了。
const foo = {
hasOwnProperty: function () {
return false;
},
bar: "Here be dragons",
};
foo.hasOwnProperty("bar"); // always returns false
// Use another Object's hasOwnProperty
// and call it with 'this' set to foo
({}.hasOwnProperty.call(foo, "bar")); // true
// It's also possible to use the hasOwnProperty property
// from the Object prototype for this purpose
Object.prototype.hasOwnProperty.call(foo, "bar"); // true
所以一般在使用 hasOwnProperty,可以自己写个函数。
function hasProp(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
lodash 库中已经有这样的轮子, has(),推荐使用。
总结:推荐使用hasOwnProperty,但不是直接使用。建议使用 lodash 中的has()或是自己的封装。
prop in myObject
in操作符也可以用来判断一个对象是否有给定的 Property。
const demoObject = {
name: "Demo",
favouriteDrink: null,
cool: false,
};
"cool" in demoObject; // true
in的问题也是会查看 prototype 链。所以也不太靠谱。
// inherits Object.prototype.toString
"toString" in demoObject; // true
总结:可以使用,但不是太推荐。
typeof
if (typeof demoObject.name !== "undefined") {
// do something
}
总结:鉴于null, undefined的不可靠性,这样的写法可阅读性太差了。不推荐。
检测特性(feature)
if ("draggable" in document.createElement("div")) {
// do something if prop exists
}