JS中for...in?和?for...of?的區(qū)別解析
1. 迭代的對象不同
- for … in 用于迭代對象的可枚舉字符串屬性,包括自身屬性和繼承的屬性,但不會遍歷對象的原型鏈上的 非可枚舉屬性,以及對象的方法。
從內(nèi)置構(gòu)造函數(shù)(如 Array 和 Object)創(chuàng)建的對象會從 Array.prototype 和 Object.prototype 繼承不可枚舉屬性,例如 Array 的 indexOf() 方法或 Object 的 toString() 方法,它們在 for…in 循環(huán)中不會被訪問到。
- for … of 用于迭代可迭代對象定義的要進行迭代的值。可迭代對象 包括 數(shù)組、字符串、Set、Map等,還包括 arguments 對象。它遍歷的是可迭代對象的迭代器(Iterator)返回的值或鍵值對,而不能直接用于普通的對象。
當(dāng) for…of 循環(huán)迭代一個可迭代對象時,它首先調(diào)用可迭代對象的 @@iterator 方法,該方法返回一個迭代器,然后重復(fù)調(diào)用生成器的 next() 方法,以生成要分配給 每次循環(huán)迭代的 可迭代對象 的值的序列。
注意: 每次迭代都會創(chuàng)建一個新的變量。在循環(huán)體內(nèi)部重新賦值變量不會影響可迭代對象的原始值。
要成為可迭代對象,必須要有一個迭代器 @@iterator方法,也就是說這個對象必須有一個鍵為@@iterator的屬性,通過常量 Symbol.iterator 訪問這個屬性,并返回一個迭代器對象
迭代器對象包含一個 next() 方法,無參數(shù)或者接受一個參數(shù)的函數(shù),并返回符合 IteratorResult 接口的對象。
next() 方法會返回一個具有 value 和 done 屬性的對象。
- value 表示當(dāng)前迭代的值。如果迭代器已經(jīng)到達末尾,那么 value 的值通常為 undefined,但這并不是必然的,具體取決于迭代器的實現(xiàn)。
- done 是一個布爾值,表示迭代是否已完成。迭代器是否已完成遍歷。當(dāng)遍歷結(jié)束時,done 為 true,否則為 false。
實際上,兩者都不是嚴格要求的;如果返回沒有任何屬性的對象,則實際上等價于
{ done: false, value: undefined }。
const obj = {
a: 1,
b: { h:123 },
};
//定義在自身的屬性
Object.defineProperty(obj, 'c', {
value: 3,
});
//定義在自身的屬性
Object.defineProperty(obj, 'd', {
value: 4,
enumerable: true,//是否可枚舉,默認false不可枚舉
});
//定義在原型上的屬性
Object.prototype.e=5;
for (let key in obj) {
console.log(key); // 輸出 'a' 、 'b'、 'd'、'e',但不會輸出 'c'、'h'
}
console.log(Object.keys(obj)); // 輸出 ['a', 'b','d'],不包括 'c'、'e'、'h'
console.log(Object.getOwnPropertyNames(obj)); // 輸出 ['a', 'b', 'c','d'],包括 'c', 但不包括'e'、'h'擴展:
Object.keys 會返回一個包含所有可枚舉的自有字符串屬性的數(shù)組,Object.getOwnPropertyNames 則會包含所有屬性,包括不可枚舉的。Object.getOwnPropertyDescriptor(obj, prop)靜態(tài)方法返回一個對象,該對象描述給定對象上特定屬性(即直接存在于對象上而不在對象的原型鏈中的屬性)的配置。
obj
要查找其屬性的對象。
prop
要檢索其描述的屬性的名稱或 Symbol。
返回值
如果指定的屬性存在于對象上,則返回其屬性描述符,否則返回 undefined。
// 對象本身的屬性的屬性描述符
const desc = Object.getOwnPropertyDescriptor(obj, "c");
console.log(desc);
// {
// value: 3,
// writable: false,
// enumerable: false,
// configurable: false
// }
// 對象原型上的屬性的屬性描述符
const desc1 = Object.getOwnPropertyDescriptor(Object.prototype, "e");
console.log(desc1);
//{
// value: 5,
// writable: true,
// enumerable: true,
// configurable: true
// }屬性描述符
- value
與屬性關(guān)聯(lián)的值(僅限數(shù)據(jù)描述符)。
- writable :是否可更改
當(dāng)且僅當(dāng)與屬性關(guān)聯(lián)的值可以更改時,為 true(僅限數(shù)據(jù)描述符)。
- enumerable : 是否可枚舉
當(dāng)且僅當(dāng)此屬性在相應(yīng)對象的屬性枚舉中出現(xiàn)時,為 true。
- configurable :是否可刪除
當(dāng)且僅當(dāng)此屬性描述符的類型可以更改且該屬性可以從相應(yīng)對象中刪除時,為 true。
在迭代 Array 時,for…of 循環(huán)和 for…in 循環(huán)之間的區(qū)別。
Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};
const iterable = [3, 5, 7];
iterable.foo = "hello";
for (const i in iterable) {
console.log(i);
}
// "0"、"1"、"2"、"foo"、"arrCustom"、"objCustom"
for (const i in iterable) {
if (Object.hasOwn(iterable, i)) {
console.log(i);
}
}
// "0" "1" "2" "foo"
for (const i of iterable) {
console.log(i);
}
// 3 5 7使用 Object.hasOwn() 來檢查找到的可枚舉屬性是否為對象的自有屬性,即非繼承屬性。
const arr=['A','B', ,'D', ,'F'];
for(const key in arr){
console.log(key); //0,1,3,5
}
for(const item of arr){
console.log(item); // A,B,undefined,D,undefined,F
}for…in 使用屬性枚舉而不是數(shù)組的迭代器。在稀疏數(shù)組中,for…of 會訪問空槽,但 for…in 不會訪問空槽。
2. 遍歷順序
- for … in 循環(huán)遍歷對象屬性時,遍歷的順序是不確定的,因為對象屬性沒有固定的順序。
根據(jù)現(xiàn)代 ECMAScript 規(guī)范的定義,遍歷的順序是一致且可預(yù)測的。在原型鏈的每個組件中,所有非負整數(shù)鍵(可以作為數(shù)組索引)將首先按值升序遍歷,然后是其他字符串鍵按屬性創(chuàng)建的先后順序升序遍歷。
- for … of 循環(huán)遍歷可迭代對象時,遍歷的順序是按照對象的迭代器定義的順序進行的。
3. 可迭代性要求
- for … in 循環(huán)不需要對象滿足可迭代性要求。
- for … of 循環(huán)要求被遍歷的對象必須是可迭代對象(實現(xiàn)了迭代器接口)。如果對象沒有迭代器接口,嘗試使用 for … of 循環(huán)會拋出錯誤。
總的來說:
- for…in 循環(huán)用于迭代對象的可枚舉字符串屬性,包括自身屬性和繼承的屬性,
- for…of 循環(huán)用于迭代可迭代對象定義的要進行迭代的值。
到此這篇關(guān)于JS中for...in 和 for...of 的區(qū)別的文章就介紹到這了,更多相關(guān)js for...in 和 for...of 區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 全面解析JavaScript里的循環(huán)方法之forEach,for-in,for-of
- 詳解Js里的for…in和for…of的用法
- js遍歷詳解(forEach, map, for, for...in, for...of)
- js中forEach,for in,for of循環(huán)的用法示例小結(jié)
- js中for-in和for-of的區(qū)別詳解
- JavaScript 中for/of,for/in 的詳細介紹
- JavaScript中for-in和for-of的不同之處及如何正確使用
- JS中for,for...in,for...of和forEach的區(qū)別和用法實例
- JavaScript中for of和for in的區(qū)別詳解
- JavaScript中for in和for of的區(qū)別示例詳解
相關(guān)文章
javascript學(xué)習(xí)隨筆(使用window和frame)的技巧
javascript學(xué)習(xí)隨筆(使用window和frame)的技巧...2007-03-03
基于JavaScript實現(xiàn)快速轉(zhuǎn)換文本語言(繁體中文和簡體中文)
這篇文章主要介紹了基于JavaScript實現(xiàn)快速切換正體中文和簡體中文,需要的朋友可以參考下2016-03-03
關(guān)于TypeScript開發(fā)的6六個實用小技巧分享
TypeScript是Javascrip t超集,支持靜態(tài)類型檢測,可以在編譯期提前暴露問題,節(jié)省debug時間,下面這篇文章主要給大家介紹了關(guān)于TypeScript開發(fā)的6六個實用小技巧,需要的朋友可以參考下2021-09-09
js點擊返回跳轉(zhuǎn)到指定頁面實現(xiàn)過程
這篇文章主要為大家詳細介紹了js點擊返回跳轉(zhuǎn)到指定頁面實現(xiàn)過程,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-04-04

