在JavaScript中,我們有4種方法可以獲取對象中的屬性天试,分別是for...in目派、Object.keys()、Object.getOwnPropertyNames()夜畴、Reflect.ownKeys(),下面分別說下他們之間的區(qū)別:
for...in
for...in循環(huán)會遍歷對象自身的所有屬性拖刃,以及它原型上的屬性,并且贪绘,for...in只遍歷對象中可枚舉的屬性(enumerate為true)兑牡。像 Array 和 Object 使用內(nèi)置構(gòu)造函數(shù)所創(chuàng)建的對象都會繼承自 Object.prototype 和 String.prototype 的不可枚舉屬性。
可枚舉屬性:簡單來說就是JS對象中的屬性是否可以列舉出來税灌。
Object.keys(obj)
它可以得到自身可枚舉的屬性,但得不到原型鏈上的屬性均函,同時(shí)Symbols 屬性也得不到。
Object.getOwnPropertyNames(obj)
它可以得到自身所有的屬性(包括可枚舉屬性以及不可枚舉屬性),但得不到原型鏈上的屬性, 當(dāng)然Symbols 屬性也得不到.
Reflect.ownKeys(obj)
它可以得到對象的所有屬性菱涤,基本等同于上述的Object.getOwnPropertyNames(obj)加上Object.getOwnPropertySymbols(obj)返回之和苞也,這里的getOwnPropertySymbols方法單獨(dú)只返回對象中包含symbols屬性。
如果不夠清晰粘秆?下面我們可以使用代碼來解釋上述內(nèi)容的描述:
const animal = {
A: 1,
B: 2,
C: 3,
}
const cat = {
D: 4,
E: 5,
[Symbol()]: 6,
}
cat.__proto__ = animal
Object.defineProperty(cat, "E", { enumerable: false }); //定義E屬性為不可枚舉
for (let attrs in cat) {
console.log("for...in:", attrs) // A,B,C,D
}
console.log("Object.keys:", Object.keys(cat)) // [ 'D' ]
console.log("Object.getOwnPropertyNames:", Object.getOwnPropertyNames(cat)) // [ 'D', 'E' ]
console.log("Reflect.ownKeys:", Reflect.ownKeys(cat)) // [ 'D', 'E', Symbol() ]