一文搞懂for in、for of、Object.keys()、Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()的区别

it2024-11-14  3

获取对象不同类型属性的相关方法

一、对象属性理解

比如:数组中的length属性,描述符对象enumerable值为false,隐式属性。

看下正常的数组和对象的属性:

var arr = ["a", true, 3] var obj = { name: "zhu", age: 24 } console.log(arr) console.log(obj)

二、关于遍历

1、for...in循环(自身显式的属性,意外的获取了原型链上的属性)

只遍历显式属性和原型链上的显式属性, 当然也可以遍历数组。

var sym = Symbol("foo"); var arr = ["a", true, 3]; var obj = { name: "zhu", age: 24, [sym]: "symbol-foo", [Symbol("bar")]: "symbol-bar" } //age为隐式属性 Object.defineProperty(obj, "age", { enumerable: false }) //原型上的属性 obj.__proto__ = { fa: "father" } var objStack = []; var arrStack = []; for(var prop in obj){ objStack.push(prop) } for(var i in arr){ arrStack.push(i) } console.log(objStack) console.log(arrStack) ["name", "fa"] ["0", "1", "2"]

 所以我们在使用for in 遍历的时候,防止遍历到原型链上的属性,我们会用hasOwnProperty方法来判断是不是对象本身的属性

console.log(obj.hasOwnProperty("fa"))

 而 in 方法可以判断属性是不是对象原型及原型链上的属性

console.log("fa" in obj )

2、for...of循环 

只遍历iterable类型的值,且处理的是iterable的值,而非属性或键;对象不是iterable类型

var arrStack = []; var arr = ["a", true, 3, sym, Symbol("bar")]; for(var i of arr){ arrStack.push(i) } console.log(arrStack) //["a", true, 3, Symbol(foo), Symbol(bar)]

3、Object.keys()方法(自身显式的属性)

返回指定对象自身可枚举属性名称组成的数组。

var sym = Symbol("foo"); var arr = ["a", true, 3]; var obj = { name: "zhu", age: 24, [sym]: "symbol-foo", [Symbol("bar")]: "symbol-bar" } //age为隐式属性 Object.defineProperty(obj, "age", { enumerable: false }) //原型上的属性 obj.__proto__ = { fa: "father" } console.log(Object.keys(obj)) //["name"] console.log(Object.keys(arr)) //["0", "1", "2"]

4、Object.getOwnPropertyNames()方法——自身所有的属性

获取对象自身的所有属性,不包含Symbol属性

即自身显式的和隐式的属性

var sym = Symbol("foo"); var arr = ["a", true, 3]; var obj = { name: "zhu", age: 24, [sym]: "symbol-foo", [Symbol("bar")]: "symbol-bar" } //age为隐式属性 Object.defineProperty(obj, "age", { enumerable: false }) //原型上的属性 obj.__proto__ = { fa: "father" } console.log(Object.getOwnPropertyNames(obj)) //["name", "age"] console.log(Object.getOwnPropertyNames(arr)) //["0", "1", "2", "length"]

 5、Object.getOwnPropertySymbols()方法——自身Symbol属性

获取对象自身的Symbol属性

var sym = Symbol("foo"); var arr = ["a", true, 3]; var obj = { name: "zhu", age: 24, [sym]: "symbol-foo", [Symbol("bar")]: "symbol-bar" } //age为隐式属性 Object.defineProperty(obj, "age", { enumerable: false }) //原型上的属性 obj.__proto__ = { fa: "father" } console.log(Object.getOwnPropertySymbols(obj)) //[Symbol(foo), Symbol(bar)] console.log(Object.getOwnPropertySymbols(arr)) //[]

三、总结

(1)for in获取对象的显式属性,因为是早期版本,也会获取原型链上的显式属性

(2)Object.keys()  ES的方法,对上面方法进行优化,只获取对象本身的显式属性

(3)Object.getOwnPropertyNames()方法,获取对象自身显式的和隐式的属性

(4)Object.getOwnPropertySymbols()方法,获取对象自身的Symbol属性

 

 

最新回复(0)