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

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

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

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

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


