溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript中循環(huán)語句之間的差異

發(fā)布時間:2021-08-22 16:22:46 來源:億速云 閱讀:125 作者:chen 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“JavaScript中循環(huán)語句之間的差異”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

目錄
  • 前言

  • 可枚舉的屬性

    • 可迭代對象

  • 在 forEach 與 map 方法

    • 鏈式調(diào)用

    • 性能


前言

在 JavaScript 中使用循環(huán)時,需要正確定義兩個關(guān)鍵內(nèi)容:可枚舉屬性(enumerable properties)和可迭代對象(iterable objects)。

可枚舉的屬性

可枚舉對象的一個定義特征是,當我們通過賦值運算符將屬性賦值給對象時,我們將內(nèi)部可枚舉標志(enumerable)設(shè)置為 true。這是默認值。

但是,我們可以通過將其設(shè)置為 false 來更改此行為。

經(jīng)驗法則是,可枚舉屬性總是出現(xiàn)在 for...in 循環(huán)中。

讓我們看看這一點:

const users = {}
users.languages = 'JavaScript'

Object.getOwnPropertyDescriptor(users, 'languages')
// output -> { value: 'JavaScript', writable: true, enumerable: true, configurable: true }

// 在循環(huán)中對我們使用的屬性進行更多的控制
Object.defineProperty(users, 'role', { value: 'Admin', writable: true, enumerable: false })

for (const item in users) {
  console.log(item) // languages
}

可以看到,我們?yōu)?users 變量添加了一個 languages 屬性,使用 Object.getOwnPropertyDescriptor 方法輸出 languages 屬性描述符的 enumerable 屬性為 true。

使用 Object.defineProperty 為添加 role 屬性,并將 enumerable 設(shè)置為 false,在 for...in 循環(huán)中并沒有輸出 role 屬性。即 for...in 循環(huán)中的屬性為可枚舉屬性。

可迭代對象

如果一個對象定義了它的迭代行為,那么它是可迭代的。在本例中,將在 for...of 構(gòu)造中循環(huán)的值將定義其迭代行為??傻膬?nèi)置類型包括 Array、String、Set 和 Map 對象不可迭代,因為它沒有指定 @iterator 方法。

基本上,在 JavaScript 中,所有可迭代對象都是可枚舉對象,但并非所有可枚舉對象都是可迭代對象。

這里有一種概念化的方法:for...in 查找數(shù)據(jù)中的對象,而 for...of 查找重復(fù)序列。

讓我們看看這一切在與 Array 數(shù)據(jù)類型一起使用時的效果:

const languages = ['JavaScript', 'Python', 'Go']

// 與 for...in 循環(huán)一起使用
for (const language in languages) {
  console.log(language)
}
// output
// 0
// 1
// 2

// 與 for...of 循環(huán)一起使用
for (const language of languages) {
  console.log(author)
}
// output -> JavaScript Python Go

在使用這種構(gòu)造時,需要牢記的一點是,如果調(diào)用了 typeof,并且輸出為 object,那么您可以使用 for...in 循環(huán)。

讓我們看看這個對 languages 變量的操作:

typeof languages // "object" -> 因此我們可以在中使用 for

乍一看,這可能令人驚訝,但需要注意的是,數(shù)組是一種特殊類型的對象,以索引為鍵。知道 for...in 將在構(gòu)造中查找對象可以極大地幫助我們。當 for...in 循環(huán)找到一個對象時,它將在每個鍵上循環(huán)。

我們可以將 for ..in 循環(huán)在 languages 數(shù)組上的方式可視化如下:

const languages = {
  0: 'JavaScript',
  1: 'Python',
  2: 'Go'
}

注意:如果它可以被追蹤到一個對象(或者從對象原型鏈繼承它),for...in 將以沒有特定順序遍歷鍵。

同時,如果它實現(xiàn)了一個迭代器 for.. of 構(gòu)造,它將在每次迭代中循環(huán)遍歷該值。

在 forEach 與 map 方法

雖然 forEach 和 map 方法可以用來實現(xiàn)相同的目標,但它們的行為和性能特性有所不同。

在基本級別,當函數(shù)被調(diào)用時,它們都會接收一個回調(diào)作為參數(shù)。

考慮以下片段:

const scoresEach = [2, 4 ,8, 16, 32]
const scoresMap = [2, 4 ,8, 16, 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, 16, 64, 256, 1024]

Map 是一個純函數(shù),同時 forEach 執(zhí)行一些突變:

console.log(newScores) // [4, 16, 64, 256, 1024]

在我看來,map 支持函數(shù)式編程范式。我們不必總是執(zhí)行突變來獲得期望的結(jié)果,不像 forEach,我們必須突變 newScores 變量。在每次運行時,當提供相同的輸入時,map 函數(shù)將產(chǎn)生相同的結(jié)果。同時,forEach 對應(yīng)項將從上一個突變的先前值中提取。

鏈式調(diào)用

使用 map 可以進行鏈式調(diào)用,因為返回的結(jié)果是一個數(shù)組。因此,可以對結(jié)果立即調(diào)用任何其他數(shù)組方法。換句話說,我們可以調(diào)用 filter、reduce、some 等方法。這在 forEach 中是不可能的,因為返回的值為 undefined 的。

性能

map 方法的性能往往優(yōu)于 forEach 方法。

檢查使用 map 和 forEach 實現(xiàn)的等效代碼塊的性能。平均而言,您將看到 map 函數(shù)的執(zhí)行速度至少快 50%。

結(jié)論

在上面討論的所有循環(huán)結(jié)構(gòu)中,給我們最多控制的是 for..of 循環(huán)。我們可以將其與關(guān)鍵字 return、continue 和 break 一起使用。這意味著我們可以指定對數(shù)組中的每個元素要發(fā)生什么,以及是否要提前離開或跳過。

“JavaScript中循環(huán)語句之間的差異”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI