這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

for in 和 for of 相對于大家肯定都不陌生,都是用來遍歷屬性的沒錯,那么先看下面的一個例子:
例1
const obj = {
a: 1,
b: 2,
c: 3
}
for (let i in obj) {
console.log(i)
// a
// b
// c
}
for (let i of obj) {
console.log(i)
// Uncaught TypeError: obj is not iterable 報錯了
}
以上代碼通過 for in 和 for of 對一個obj物件進行遍歷,for in 正常的獲取了物件的 key值,分別列印 a、b、c,而 for of卻報錯了,
例2:
以上是遍歷物件,下面再看一個遍歷陣列的例子,
const arr = ['a', 'b', 'c']
// for in 回圈
for (let i in arr) {
console.log(i)
// 0
// 1
// 2
}
// for of
for (let i of arr) {
console.log(i)
// a
// b
// c
}
以上代碼是對一個陣列進行遍歷, for in 回傳的值為 0、1、2,這不是陣列的下標嗎? 而 for of 回傳的是 a、b、c,這一次沒有報錯,為什么呢?
例3
const arr = ['a', 'b']
// 手動給 arr陣列添加一個屬性
arr.name = 'qiqingfu'
// for in 回圈可以遍歷出 name 這個鍵名
for (let i in arr) {
console.log(i)
// a
// b
// name
}
for in 的特點
結合上面的兩個例子,分析得出:
-
for ... in 回圈回傳的值都是資料結構的 鍵值名,
-
遍歷物件回傳的物件的key值,遍歷陣列回傳的陣列的下標(key),
-
for ... in 回圈不僅可以遍歷數字鍵名,還會遍歷原型上的值和手動添加的其他鍵,如——例3
-
特別情況下, for ... in 回圈會以看起來任意的順序遍歷鍵名
(為什么說看起來,其實也是有規律的,這個就要扯到 常規屬性和 排序屬性,想深入學習的可以看讀李老課程引發的思考之JS設計思想篇
這里可以簡單說一下
1.什么是物件中的 常規屬性和 排序屬性
function Foo() {
this[100] = 'test-100'
this[1] = 'test-1'
this["B"] = 'bar-B'
this[50] = 'test-50'
this[9] = 'test-9'
this[8] = 'test-8'
this[3] = 'test-3'
this[5] = 'test-5'
this["A"] = 'bar-A'
this["C"] = 'bar-C'
}
var bar = new Foo()
for(key in bar){
console.log(`index:${key} value:${bar[key]}`)
}
在上?這段代碼中,我們利?建構式Foo創建了?個bar物件,在建構式中,我們給bar物件設定了很多 屬性,包括了數字屬性和字串屬性,然后我們列舉出來了bar物件中所有的屬性,并將其??列印出來, 下?就是執?這段代碼所列印出來的結果
index:1 value:test-1 index:3 value:test-3 index:5 value:test-5 index:8 value:test-8 index:9 value:test-9 index:50 value:test-50 index:100 value:test-100 index:B value:bar-B index:A value:bar-A index:C value:bar-C
觀察這段列印出來的資料,我們發現列印出來的屬性順序并不是我們設定的順序,我們設定屬性的時候是亂 序設定的,?如開始先設定100,然后有設定了1,但是輸出的內容卻?常規律,總的來說體現在以下兩 點:
設定的數字屬性被最先列印出來了,并且按照數字??的順序列印的;
設定的字串屬性依然是按照之前的設定順序列印的,?如我們是按照B、A、C的順序設定的,列印出來,依然是這個順序,
之所以出現這樣的結果,是因為在ECMAScript規范中定義了 「數字屬性應該按照索引值??升序排列,字符 串屬性根據創建時的順序升序排列,」在這?我們把物件中的數字屬性稱為 「排序屬性」,在V8中被稱為 elements,字串屬性就被稱為 「常規屬性」, 在V8中被稱為 properties,在V8內部,為了有效地提升存盤和訪問這兩種屬性的性能,分別使?了兩個 線性資料結構來分別保存排序 屬性和常規屬性,具體結構如下圖所?:

在elements物件中,會按照順序存放排序屬性,properties屬性則指向了properties對 象,在properties物件中,會按照創建時的順序保存了常規屬性,
總結一句: for in 回圈特別適合遍歷物件,
for of 特點
for of 回圈用來獲取一對鍵值對中的值,而 for in 獲取的是 鍵名
一個資料結構只要部署了 Symbol.iterator 屬性, 就被視為具有 iterator介面, 就可以使用 for of回圈,
例1這個物件,沒有 Symbol.iterator這個屬性,所以使用 for of會報 obj is not iterable
for of 不同與 forEach, 它可以與 break、continue和return 配合使用,也就是說 for of 回圈可以隨時退出回圈,
提供了遍歷所有資料結構的統一介面
哪些資料結構部署了 Symbol.iteratoer屬性了呢?
只要有 iterator 介面的資料結構,都可以使用 for of回圈,
-
陣列 Array
-
Map
-
Set
-
String
-
arguments物件
-
Nodelist物件, 就是獲取的dom串列集合
-以上這些都可以直接使用 for of 回圈, 凡是部署了 iterator 介面的資料結構也都可以使用陣列的 擴展運算子(...)、和解構賦值等操作,
我也想讓物件可以使用 for of回圈怎么辦?使用 Object.keys() 獲取物件的 key值集合后,再使用 for of
以例1為例
const obj = {
a: 1,
b: 2,
c: 3
}
for (let i of Object.keys(obj)) {
console.log(i)
// 1
// 2
// 3
}
也可以給一個物件部署 Symbol.iterator屬性,
本文轉載于:
https://juejin.cn/post/6854573212039151629
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/526015.html
標籤:JavaScript
下一篇:【Web】ES6新特性
