javascript检查属性是否存在(hasOwnProperty和propertyIsEnumerable的区别)

本贴最后更新于 3047 天前,其中的信息可能已经时异事殊

起因

JavaScript 对象就是各种属性的集合,业务场景为接收用户传来的 options 参数,如果默认 defaultOptions 存在传入的参数属性,则进行替换。所以存在一个检查对象是否包含某个属性的操作。
在原型属性中找到了 hasOwnProperty 和 propertyIsEnumerable 两个方法。那么这两个方法有什么区别呢?各自的使用场景又是什么呢?

hasOwnProperty

hasOwnProperty()方法可以接收一个字符参数,用来判断对象中是否存在以字符参数命名的属性。它只会查找自身属性,不会根据原型链进行查找。

注:原型链会再另一篇文章中做详细的介绍!

var obj = {x:"1"};
obj.y = function(){};
console.log(obj.hasOwnProperty("x")); //true
console.log(obj.hasOwnProperty("y")); //true 方法也是属性
console.log(obj.hasOwnProperty("z")); //false 属性不存在
console.log(obj.hasOwnProperty("toString")); //false hasOwnProperty是继承Object的属性,自身属性中不存在

propertyIsEnumerable

propertyIsEnumerable()方法在 hasOwnProperty()的基础上,校验属性是否为枚举属性。也就是说属性必须满足为自身属性且为枚举属性时,才会返回 true。

枚举属性

枚举属性,其实是可被枚举,表示该属性可以在对象中被遍历。JavaScript 属性默认均为枚举属性。如

var obj = {x:"1"};
Object.defineProperty(obj, 'y', {value : '2', enumerable : true });
Object.defineProperty(obj, 'z', {value : '3', enumerable : false });
console.log(obj);//Object {x: "1", y: "2", z: "3"}
for (var i in obj) {
	console.log(i); //x,y
}

上述代码中属性 z 被手动指定为非枚举属性,因此没有被遍历。
结合上面的 2 例子,可以清晰的知道 propertyIsEnumerable()函数的作用:

var obj = {x:"1"};
obj.y = function(){};
Object.defineProperty(obj, 'z', {value : '2', enumerable : true });
Object.defineProperty(obj, 'w', {value : '3', enumerable : false });
console.log(obj.propertyIsEnumerable("x")); //true 属性默认为枚举属性
console.log(obj.propertyIsEnumerable("y")); //true 方法也是属性
console.log(obj.propertyIsEnumerable("z")); //true
console.log(obj.propertyIsEnumerable("w")); //false 属性不是枚举属性
console.log(obj.propertyIsEnumerable("v")); //false 属性不存在
console.log(obj.propertyIsEnumerable("toString")); //false propertyIsEnumerable是继承Object的属性,自身属性中不存在

扩展一 !== 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

为了避免!==undefined 带来的歧义,可以使用 in 运算符进行属性存在的检测。in 是根据属性,而不是通过属性值来判断是否存在。

var obj = {x:"1", y:undefined, z:null};
console.log("x" in obj); //true 属性存在
console.log("y" in obj); //true 属性存在
console.log("z" in obj); //true 属性存在
console.log("w" in obj); //false 属性不存在
console.log("toString" in obj); //true 属性存在

总结

  • hasOwnProperty 自身存在的属性
  • propertyIsEnumerable 自身存在的属性,且为枚举属性
  • !== undefined 自身存在的属性,继承的属性,不能识别值为 undefined 的属性
  • in 自身存在的属性,继承的属性

根据具体业务场景,自由选择或组合对应的方法,可以实现对属性的检测。

打赏 100 积分后可见
100 积分
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    710 引用 • 1173 回帖 • 171 关注
  • hasOwnProperty
    1 引用 • 1 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...