前言
记录我在判断一个对象有没有某一个属性时的一些总结,错误方法是踩过的坑,只想看判断方法可以直接跳到正确方法部分。
错误方法
如果我们想判断一个对象有没有某一个属性,不能用对象.属性名
或者对象[属性名]
的方式,这种方式实现的功能是判断对象的属性值是否为真。
var str = 'abcoefoxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); // chars 是 字符串的每一个字符
if (o[chars]) { // o[chars] 得到的是属性值
o[chars]++;
} else {
o[chars] = 1;
}
}
上边代码想实现的功能是统计字符串中每个字符的出现次数,其中利用了一个对象来保存每个字符的出现次数,字符名为对象的属性,出现次数为属性值。
表面上看,if (o[chars])
似乎可以实现判断对象中某个属性是否存在的功能,程序也会得到正确的输出。
但是实际上,如果对象没有某个属性,那么其属性值为undefined,Js会将undefined自动转为false。
这种方式在一些场景下是可以使用的,但是若对象有某个属性且属性值为false,就会出现问题:
var o = {
age: 18,
sex: false
}
if (o['sex']) {
console.log('里面有该属性');
} else {
console.log('没有该属性');
}
//上方代码会输出 没有该属性
上边代码我们想实现的是判断对象有没有sex属性,但是其实实现的效果是判断对象sex属性的值是否为真。
如果在某些情况下采用对象.属性名
或者对象[属性名]
的方式,也要用 []
而不是 .
来调用对象的属性,因为[]
能很好的区分变量和常量,而 .
会把变量当作常量。
同样是上边的代码,如果用 .
调用对象的属性,会把chars这个变量当作一个属性,所以我们得到的o对象只有一个chars属性,其值为15(str的长度为15)
var str = 'abcoefoxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); // chars 是 字符串的每一个字符
if (o.chars) { // o[chars] 得到的是属性值
o.chars++;
} else {
o.chars = 1;
}
}
正确方法
Object.prototype.hasOwnProperty()
hasOwnProperty()
方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性, 会忽略掉那些从原型链上继承到的属性。
var o = {
age: 18,
sex: false
}
if (o.hasOwnProperty('sex')) {
console.log('里面有该属性');
} else {
console.log('没有该属性');
}
//输出 里面有该属性
in运算符
如果指定的属性在指定的对象或其原型链中,则in
运算符返回true
。
const car = {
make: 'Honda',
model: 'Accord',
year: 1998
};
console.log('make' in car); // true
delete car.make;
console.log('make' in car); // false
console.log('toString' in car) // true