詳細談談JavaScript中迴圈之間的差異
目錄
- 前言
- 可列舉的屬性
- 可迭代物件
- 在 forEach 與 map 方法
- 鏈式呼叫
- 效能
- 結論
前言
在 中使用迴圈時,需要正確定義兩個關鍵內容:可列舉屬性(enumerable properties)和可迭代物件(iterable objects)。
可列舉的屬性
可列舉物件的一個定義特徵是,當我們通過賦值運算子將屬性賦值給物件時,我們將內部可列舉標誌(enumerable)設定為 true。這是預設值。
但是,我們可以通過將其設定為 false 來更改此行為。
經驗法則是,可列舉屬性總是出現在 for...in 迴圈中。
讓我們看看這一點:
const users = {} users.languages = 'Script' Object.getOwnPropertyDescriptor(users,'languages') // output -> { value: 'JavaScript',writable: true,enumerable: true,configurawyvRUcNtbble: true } // 在迴圈中對我們使用的屬性進行更多的控制 Object.defineProperty(users,'role',{ value: 'Admin',enumerable: false }) for (const item in users) { console.log(item) // languages }
可以看到,我們為 users 變數添加了一個 languages 屬性,使用 Object.getOwnPropertyDescriptor 方法輸出 languages 屬性描述符的 enumerable 屬性為 true。
使用 Object.defineProperty 為新增 role 屬性,並將 enumerable 設定為 false,在 for...in 迴圈中並沒有輸出 role 屬性。即 for...in 迴圈中的屬性為可列舉屬性。
可迭代物件
如果一個物件定義了它的迭代行為,那麼它是可迭代的。在本例中,將在 for...of 構造中迴圈的值將定義其迭代行為。可迭代的內建型別包括 Array、String、Set 和 Map 物件不可迭代,因為它沒有指定 @iterator 方法。
基本上,在 JavaScript 中,所有可迭代物件都是可列舉物件,但並非所有可列舉物件都是可迭代物件。
這裡有一種概念化的方法:for...in 查詢資料中的物件,而 for...of 查詢重複序列。
讓我們看看這一切在與 Array 資料型別一起使用時的效果:
const languages = ['JavaScript','','Go'] // 與 for...in 迴圈一起使用 for (const language in languages) { console.log(language) } // output // 0 // 1 // 2 // 與 for...of 迴圈一起使用 for (const language of languages) { console.log(author) }http://www.cppcns.com// output -> JavaScript Python Go
在使用這種構造時,需要牢記的一點是,如果呼叫了 typeof,並且輸出為 object,那麼您可以使用 for...in 迴圈。
讓我們看看這個對 languages 變數的操作:
typeof languages // "object" -> 因此我們可以在中使wyvRUcNtb用 for
乍一看,這可能令人驚訝,但需要注意的是,陣列是一種特殊型別的物件,以索引為鍵。知道 for...in 將在構造中查詢物件可以極大地幫助我們。當 for...in 迴圈找到一個物件時,它將在每個鍵上迴圈。
我們可以將 for ..in 迴圈在 languages 陣列上的方式視覺化如下:
const languages = { 0: 'JavaScript',1: 'Python',2: 'Go' }
注意:如果它可以被追蹤到一個物件(或者從物件原型鏈繼承它),for...in 將以沒有特定順序遍歷鍵。www.cppcns.com
同時,如果它實現了一個迭代器 for.. of 構造,它將在每次迭代中迴圈遍歷該值。
在 forEach 與 map 方法
雖然 forEach 和 map 方法可以用來實現相同的目標,但它們的行為和效能特性有所不同。
在基本級別,當函式被呼叫時,它們都會接收一個回撥作為引數。
考慮以下片段:
const scoresEach = [2,4,8,16,32] const scoresMap = [2,32] const square = (num) => num * num
讓我們詳細介紹一下它們在操作上的一些差異。
forEach 返回 undefined,而 map 返回一個新的 array:
let newScores = [] const resultWithEach = scoresEach.forEach(score => { const newScore = square(score) newScores.push(newScore) }) const resultWithMap = scoresMap.map(square) console.log(resultWithEach) // undefined console.log(resultWithMap) // [4,64,256,1024]
Map 是一個純函式,同時 forEach 執行一些突變:
console.log(newScores) // [4,1024]
在我看來,map 支援函式式正規化。我們不必總是執行突變來獲得期望的結果,不像 forEach,我們必須突變 newScores 變數。在每次執行時,當提供相同的輸入時,map 函式將產生相同的結果。同時,forEach 對應項將從上一個突變的先前值中提取。
鏈式呼叫
使用 map 可以進行鏈式呼叫,因為返回的結果是一個數組。因此,可以對結果立即呼叫任何其他陣列方法。換句話說,我們可以呼叫 filter、reduce、some 等方法。這在 forEach 中是不可能的,因為返回的值為 undefined 的。
效能
map 方法的效能往往優於 forEach 方法。
檢查使用 map 和 forEach 實現的等效程式碼塊的效能。平均而言,您將看到 map 函式的執行速度至少快 50%。
結論
在上面討論的所有迴圈結構中,給我們最多控制的是 for..of 迴圈。我們可以將其與關鍵字 return、continue 和 break 一起使用。這意味著我們可以指定對陣列中的每個元素要發生什麼,以及是否要提前離開或跳過。
到此這篇關於JavaScript中迴圈之間差異的文章就介紹到這了,更多相關JavaScript迴圈差異內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!