JavaScript对象可以看作是一个属性的集合,很多时候需要看某个属性是否存在于某个对象中。在JavaScript中对象属性的检测主要有以下几种方法。
in
运算符hasOwnProperty()
方法propertyIsEnumerable()
方法!==undefined
接下来看这四种方法怎么检测对象属性。
in
运算符
使用in
运算符可以检测对象属性,如果指定的属性存在于指定的对象中,就会返回true
,反之返回的是false
。
下面的例子演示了in
是如何检测对象属性的。
var myCar = {
'make': 'Honda',
'model': 'Accord',
'year': 1998
}
'make' in myCar; // true
'name' in myCar; // false
'toString' in myCar; // true
在使用in
运算符做对象属性检测时,运算符右侧必须是一个对象,比如可以是一个string
包装的对象,但不能是一个字符串原始值。
var name = new String('w3cplus');
'length' in name; // true
'w3cplus' in name; // false
// Chrome输出
name => String {0: "w", 1: "3", 2: "c", 3: "p", 4: "l", 5: "u", 6: "s", length: 7, [[PrimitiveValue]]: "w3cplus"}
typeof name => object
var name = 'w3cplus';
'length' in name; //false
'w3cplus' in name; // false
// Chrome输出
name => "w3cplus"
typeof name => string
使用delete
运算符删除了一个对象一个属性,这时使用in
运算符检测删除的属性时会返回false
:
var obj = {
'name': 'w3cplus',
'type': 'blog'
}
delete obj.name; // Object {type: "blog"}
name in obj; // false
如果你只是将一个属性的值赋值为undefined
,而没有用delete
删除它,这个时候使用in
运算符检测对象属性时依旧会返回true
。
var obj = {
'name': 'w3cplus',
'type': 'blog'
}
obj.url = undefined;
'url' in obj; // true
hasOwnProperty()
方法
使用hasOwnProperty()
方法可以判断某个对象是否含有指定的自身属性。使用这个方法,所有承继继承了Object.prototype
的对象都会从原型链上继承到hasOwnProperty()
方法上。而且该方法会忽略掉那些从原型上继承到的属性。
如果对象obj
包含指定的prop
属性的话,使用hasOwnProperty()
方法将返回true
值,反之将会返回false
。
先来看个简单示例:
var obj = {
'name': 'w3cplus',
'type': 'blog'
}
obj.hasOwnProperty('name'); // true
obj.hasOwnProperty('toString'); // false
只有hasOwnProperty()
可以给出正确和期望的结果,这在遍历对象的属性时会很有用。 没有其它方法可以用来排除原型链上的属性,而不是定义在对象自身上的属性。
hasOwnProperty()
方法只会查找自身属性,不会根据原型链进行查找。而且hasOwnProperty()
方法在碰到对象拥有自已的hasOwnProperty
方法时,其原型链上的同名方法hasOwnProperty()
就会被遮蔽。
var foo = {
hasOwnProperty: function() {
return false;
},
bar: 'Here be dragons'
};
foo.hasOwnProperty('bar'); // 始终返回 false
如果担心hasOwnProperty()
方法有可能被遮蔽的这种情况,可以直接使用原型链上真正的 hasOwnProperty
方法:
({}).hasOwnProperty.call(foo, 'bar'); // true
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true
propertyIsEnumerable()
方法
propertyIsEnumerable()
方法是hasOwnProperty()
方法的一个升级版。在JavaScript中每个对象都有一个propertyIsEnumerable()
方法。使用这个方法可以判断出指定的对象obj
里的属性prop
是否可枚举,也就是说该属性是否可以通过for...in
循环遍历到,不过有些属性虽然可以通过 for...in
循环遍历到,但因为它们不是自身属性,而是从原型链上继承的属性,所以该方法也会返回false
。如果对象没有指定的属性,该方法返回 false
。
先来看一个propertyIsEnumerable()
方法在普通对象和数组上的基本用法:
var obj = {};
obj.name = 'w3cplus is website';
obj.type = 'blog';
obj.propertyIsEnumerable('name'); // true
obj.propertyIsEnumerable('type'); // true
obj.propertyIsEnumerable(0); // false
obj.propertyIsEnumerable('toString'); // false
!==undefined
还有一种简单的方法可以判断对象的属性是否存在,通过属性!== undefined
来判断。此时会检测自身和继承来的属性。之所以使用!==
而不是!=
是因为!==
可以区分undefined
和null
。但是此方法有一个弊端,当属性存在且值为undefined
时,无法做出准确判断。如:
var obj = {
x:"1",
y:undefined,
z:null
};
console.log(obj.x !== undefined); //true 属性存在
console.log(obj.y !== undefined); //false 此时会出现歧义,不能准确判断属性是不存在还是属性值为undefined
console.log(obj.z !== undefined); //true 属性存在
console.log(obj.z != undefined); //false != 不能区分undefined和null,将两者同等对待
console.log(obj.w !== undefined); //false 属性不存在
console.log(obj.toString !== undefined); //true 存在toString函数属性。
然而有一种场景只能使用in
运算符,而不能使用上述属性访问的方式。in
可以区分不存在的属性和存在的属性但其值为undefined
。如下面的代码所示:
var obj = {
x : undefined // 属性显式赋值为undefined
}
obj.x !== undefined; //false,属性存在,但值为undefined
obj.y !== undefined; //false,属性不存在
"x" in obj; // true 属性存
"y" in obj; // false 属性不存在
delete obj.x; // 删除属性x
"x" in obj; // false 属性不存
总结
上面简单的整理了几种对象属性检测的方法,下面简单的做一下相关的总结:
in
自身存在的属性,继承的属性,返回true
hasOwnProperty()
自身存在的属性返回true
,继承属性返回false
propertyIsEnumerable()
自身存在的属性,且为枚举属性返回true
,!== undefined
自身存在的属性,继承的属性,不能识别值为undefined
的属性
初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。
如需转载,烦请注明出处:http://www.w3cplus.com/javascript/object-properties-detection-method.html