推荐是使用 in 去判断
通常想到的方式是 Object.hasOwnProperty(prop)
或者是 遍历keys去 includes()
hasOwnProperty
function hasProperty(obj, key) {
return obj.hasOwnProperty(key)
}
let a = { a: 1, b: 2 }
Object.defineProperty(a, "c", {
configurable: true,
writable: true,
enumerable: true,
value: 123
})
a.c = 123
console.log(hasProperty(a, "c")); //true
console.log(hasProperty(a, "toString")); //false
通过代码运行可以看出,hasOwnPropertyu 可以打印出对象的自身属性,而原型链上的继承属性却打印不了
keys
function hasProperty(obj, key) {
return Object.keys(obj).includes(key)
}
let a = { a: 1, b: 2 }
Object.defineProperty(a, "c", {
configurable: true,
enumerable: false, //该属性的键 不可被迭代 和 枚举出 也就是 Object.keys无法获取到该 键
get() {
return value
},
set(b) {
value = b
}
})
a.c = 12312
console.log(hasProperty(a, "c")); //false
console.log(hasProperty(a, "toString")); //false
console.log(a.c); //12312
通过代码运行可以看出,便利Object的keys 的方式,只能判断obj本身的可枚举的值,原型链上以及本身通过enumerable设置false的属性是无法判断的
in
function hasProperty(obj, key) {
return key in obj
}
let a = { a: 1, b: 2 }
Object.defineProperty(a, "c", {
configurable: true,
enumerable: false,
get() {
return value
},
set(b) {
value = b
}
})
a.c = 12312
console.log(hasProperty(a, "c")); //true
console.log(hasProperty(a, "toString")); //true
console.log(a.c);
使用in 不会存在上述的两个问题,可以完全判断出key是否存在的场景