【每日一題NO.57】for...in和Object.keys()的區(qū)別是什么?

目錄:
前言
相同點(diǎn):
二者的用法:
不同點(diǎn)總結(jié):
用法不同
迭代的范圍不同
前言
之前一篇文章里總結(jié)過(guò)Reflect.ownKeys()與Object.keys()的區(qū)別:

在文章最后也擴(kuò)展總結(jié)了for...in與這兩者的區(qū)別。
并且還列了一個(gè)清晰明了的表格:

今天我們?cè)賮?lái)回顧下這塊知識(shí),最后也會(huì)在下一篇再擴(kuò)展一下for、for...in、for...of的相關(guān)知識(shí)。
相同點(diǎn):
二者都可以用來(lái)迭代對(duì)象,但是語(yǔ)法不一樣、用法也不一樣,就連迭代對(duì)象的結(jié)果也不一樣。
二者的用法:
首先我們先來(lái)回憶下二者的用法:先定義一個(gè)對(duì)象用來(lái)使用,對(duì)象除了自己的實(shí)例屬性,還有原型上的firstName屬性。
const?obj?=?{?name:?'小石頭',?age:?18?}
obj.__proto__.firstName?=?'郭'
可以看到對(duì)象的屬性及原型鏈關(guān)系如下圖:
for...in
for...in 是 JavaScript 中最常見(jiàn)的迭代語(yǔ)句,我們常常使用他迭代對(duì)象的屬性,可以看到不光循環(huán)取出了對(duì)象上的屬性,就連原型上firstName屬性也被取出來(lái)了。
for?(?let?o?in?obj)?{
??console.log(o)?//?name、age、firstName
??console.log(obj[o])?//?'小石頭'、18、郭
}
for...in 循環(huán)會(huì)枚舉對(duì)象原型鏈上的可枚舉屬性
所以有時(shí)候你會(huì)看到這么使用,用Object.hasOwnProperty()方法將原型上的數(shù)據(jù)過(guò)濾掉。
for?(const?key?in?obj)?{
??if?(Object.hasOwnProperty.call(object,?key))?{
????const?value?=?obj[key];
????console.log(`當(dāng)前鍵名是:${key},對(duì)應(yīng)的值為${value}`);
??}
}
這樣就不會(huì)拿到原型上的屬性了,循環(huán)打印結(jié)果如下:

Object.keys()
使用Object.keys()將目標(biāo)對(duì)象作為參數(shù)傳進(jìn)去后,得到一個(gè)對(duì)象所有可枚舉屬性名組成的數(shù)組。但是沒(méi)有拿到對(duì)象原型鏈上的屬性。
const?keyArray?=?Object.keys(obj);?//?['name',?'age']
tips:數(shù)組中屬性名的順序跟使用 for…in 遍歷返回的順序是一樣的。
不同點(diǎn)總結(jié):
用法不同
for…in是遍歷對(duì)象取出可枚舉屬性的值。而Object.keys()是得到對(duì)象所有可枚舉屬性組成的數(shù)組。
如果你想獲取一個(gè)對(duì)象的所有屬性,,甚至包括不可枚舉的,請(qǐng)查看Object.getOwnPropertyNames[1]
迭代的范圍不同
for…in可以得到對(duì)象原型鏈上的可枚舉屬性,Object.keys()不行。
參考資料
Object.getOwnPropertyNames: 可以看MDN相關(guān)文章https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
所有《每日一題》的 知識(shí)大綱索引腦圖 整理在此:https://www.yuque.com/dfe_evernote/interview/everyday


