溫馨提示×

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

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

javascript中3種for循環(huán)風(fēng)格的使用示例

發(fā)布時(shí)間:2020-12-01 08:52:44 來(lái)源:億速云 閱讀:166 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要介紹javascript中3種for循環(huán)風(fēng)格的使用示例,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

在學(xué)習(xí)任何開(kāi)發(fā)語(yǔ)言時(shí)候,for循環(huán)是必不可少的一種語(yǔ)法,可能所有開(kāi)發(fā)人員都會(huì)使用它。它非常經(jīng)典,以至于每個(gè)開(kāi)發(fā)語(yǔ)言都至少包括一種關(guān)于循環(huán)的語(yǔ)法版本。不過(guò),在JavaScript種包含了三種不同的循環(huán)語(yǔ)法(如果再講究一點(diǎn),也可以算作是四種)。

它們的使用方式并不完全相同,舉例如下:

l  經(jīng)典的For循環(huán)語(yǔ)法

l  For….of 及 For…in

l  炫技一點(diǎn)的版本:.forEach

接下來(lái),我想介紹下這三種語(yǔ)法使用時(shí)有什么異同,以及在什么時(shí)間怎樣使用它們才能收獲最棒的結(jié)果。好的,讓我們開(kāi)始吧。

經(jīng)典的For循環(huán)

這個(gè)語(yǔ)法我們應(yīng)該都已經(jīng)非常清楚了,在for循環(huán)中,你可以在其中定義內(nèi)部計(jì)數(shù)器,設(shè)置相應(yīng)中斷條件和靈活的步進(jìn)策略(通??梢允沁f增也可以是遞減)。

語(yǔ)法為:

for([計(jì)數(shù)器定義];[中斷條件];[步進(jìn)策略]){
   //... 
    TODO
}

我敢肯定即便不用我的介紹,之前你也一定寫過(guò)類似的語(yǔ)句,例如:

for(let counter = 0; counter < 10; counter++) {
console.log(counter)
}

讓我們?cè)贑hrome里運(yùn)行一下,得到的結(jié)果也符合預(yù)期,但for循環(huán)就僅僅如此了嗎?

javascript中3種for循環(huán)風(fēng)格的使用示例

你可以認(rèn)為for循環(huán)為三個(gè)表達(dá)式

for(
[在循環(huán)開(kāi)始時(shí)只執(zhí)行一次的表達(dá)式];
[其中每一個(gè)邏輯判斷都需吻合的表達(dá)式];
[循環(huán)每一步都被執(zhí)行的表達(dá)式]
)

這樣表述的意義在于,你可以使用多個(gè)計(jì)數(shù)器執(zhí)行for循環(huán),或在不影響計(jì)數(shù)器的情況下在步進(jìn)表達(dá)式中執(zhí)行每次需要執(zhí)行的代碼,舉個(gè)例子:

for(let a = 0, b = 0; a < 10 && b < 100; a++, b+=10) {
   console.log(a, b)
}

javascript中3種for循環(huán)風(fēng)格的使用示例

我們可以再進(jìn)一步,讓其變的更符合實(shí)際應(yīng)用場(chǎng)景:

for(let a = 0, b = 0; a < 10 && b < 100; console.log("你的計(jì)數(shù)器現(xiàn)在是:", ++a, b+=2)){}

javascript中3種for循環(huán)風(fēng)格的使用示例

另外,你甚至可以把中間表達(dá)式替換為函數(shù)調(diào)用,只要你記住,該函數(shù)的返回值需要是一個(gè)布爾型或可以被轉(zhuǎn)成布爾值的一個(gè)值即可,例如:

function isItDone(a) {
 console.log("函數(shù)被調(diào)用!")
 return a < 10
}

for(let a = 0; isItDone(a); a++) {
 console.log(a)
}

javascript中3種for循環(huán)風(fēng)格的使用示例

那么,在經(jīng)典的for循環(huán)中如何處理異步代碼呢?如何保證不掉進(jìn)異步陷阱里呢?

我為大家介紹一位新朋友:async / await,這將讓我們?cè)谔幚懋惒酱a時(shí)變得更容易、可控,例如:

const fs = require("fs")

async function read(fname) {
    return new Promise( (resolve, reject) => {
        fs.readFile(fname, (err, content) => {
            if(err) return reject(err)
            resolve(content.toString())
        })
    })
}

(async () => {
    let files = ['file1.json', 'file2.json']

    for(let i = 0; i < files.length; i++) {
        let fcontent = await read(files[i])
        console.log(fcontent)
        console.log("-------")
    }
})()

For... in 及 For… of

他們看起來(lái)非常相似,但它們并不是相同類型的循環(huán)。

讓我們盡量簡(jiǎn)要的解釋它們:

For…in 循環(huán)遍歷對(duì)象的可枚舉屬性,也就是說(shuō)當(dāng)你的自定義對(duì)象被用作哈希表或字典時(shí),使用For…in 遍歷他們時(shí)將變得非常簡(jiǎn)單。

但請(qǐng)注意,遍歷順序是按元素順序執(zhí)行執(zhí)行的,因此請(qǐng)不要依賴循環(huán)順序。

let myMap {
  uno: 1,
  dos: 2,
  tres: 3
}
for(let key in myMap) {
  console.log(key, "=", myMap[key]);
}

看起來(lái)是很簡(jiǎn)單的,但請(qǐng)記住,F(xiàn)or…in只能遍歷一個(gè)實(shí)體對(duì)象,如果便利一個(gè)非實(shí)體,例如遍歷一個(gè)string,那么將會(huì)發(fā)生如下情況:

for(let k in "Hello World!") {
   console.log(k)
}

javascript中3種for循環(huán)風(fēng)格的使用示例

從結(jié)果可以看到,并沒(méi)有遍歷出每一個(gè)字母,而是遍歷到了每個(gè)屬性,正如您看到的,遍歷出的數(shù)字并非是沒(méi)有用的,因?yàn)?quot;Hello World!"[1] 同樣是可以返回相應(yīng)的字母的。

相反,如果你想遍歷每個(gè)字符,則需要使用其他變體:For…of

for(let char of "Hello World!") {
  console.log(char)
}

javascript中3種for循環(huán)風(fēng)格的使用示例

這種循環(huán)方式看起來(lái)對(duì)string類型更有效,相同的用例,因?yàn)槭褂昧诉@種語(yǔ)法,就能夠返回元素中相應(yīng)的值了。所以我們通過(guò)上述用例可知,F(xiàn)or…of遍歷的內(nèi)容是對(duì)象的值。

通過(guò)上述的示例我們可知,他們相互一個(gè)遍歷屬性,一個(gè)遍歷值,那么有沒(méi)有什么方法可以既獲得屬性又獲得值呢,答案是有的,使用entries方法,就可以同時(shí)獲得屬性和值,如下所示:

let myArr = ["hello", "world"]
for([idx, value] of myArr.entries()) {
    console.log(idx, '=', value)
}

javascript中3種for循環(huán)風(fēng)格的使用示例

最后,在處理異步代碼時(shí)是怎樣的呢?答案當(dāng)然是和for循環(huán)相同了。

const fs = require("fs")

async function read(fname) {
    return new Promise( (resolve, reject) => {
        fs.readFile(fname, (err, content) => {
            if(err) return reject(err)
            resolve(content.toString())
        })
    })
}



(async () => {
    let files = ['file2.json', 'file2.json']

    for(fname of files) {
        let fcontent = await read(fname)
        console.log(fcontent)
        console.log("-------")
    }

    for(idx in files) {
        let fcontent = await read(files[idx])
        console.log(fcontent)
        console.log("-------")
    }
})()

最后我們?cè)偈褂煤?jiǎn)短的方式來(lái)總結(jié)下For…in和For…of的區(qū)別

For…in——遍歷屬性

For…of——遍歷值

.forEach 循環(huán)

這可能是我最喜歡的一個(gè),這僅僅是因?yàn)槲曳浅O矚g聲明式語(yǔ)法或通過(guò)命令式編寫代碼的聲明性方式。

而且,盡管上面的循環(huán)語(yǔ)法也很好用,并且都有很好的用例,但當(dāng)我們需要關(guān)注數(shù)據(jù)本身時(shí),forEach很好用。

不管怎樣,先撇開(kāi)哲學(xué)上的爭(zhēng)論不談,.foreach方法是for循環(huán)的另一個(gè)版本,但是這個(gè)方法是數(shù)組對(duì)象的一部分,它的目的是接收一個(gè)函數(shù)和一個(gè)額外的可選參數(shù),以便在執(zhí)行函數(shù)時(shí)重新定義該函數(shù)的上下文。

對(duì)于數(shù)組中的每個(gè)元素,我們的函數(shù)都將被執(zhí)行,并且它將收到三個(gè)參數(shù)(是的,就是三個(gè),而不是一個(gè),因?yàn)槟呀?jīng)習(xí)慣了使用它)。它們分別是:

  • 正在處理的當(dāng)前元素。

  • 元素的索引,這已經(jīng)簡(jiǎn)化了我們?cè)噲D用for…of循環(huán)實(shí)現(xiàn)的任務(wù)

  • 正在處理的實(shí)際數(shù)組。以防萬(wàn)一你需要做點(diǎn)什么。

那么,讓我們看一個(gè)簡(jiǎn)單的示例:

a = ["hello", "world"]

a.forEach ( (elem, idx, arr) => {
   console.log(elem, "at: ", idx, "inside: ", arr)
})

javascript中3種for循環(huán)風(fēng)格的使用示例

更快更簡(jiǎn)單,不是嗎?

但是你可以看到我們?nèi)绾卧诤瘮?shù)中很容易地使用所有屬性。下面是一個(gè)您希望在foreach方法上使用第二個(gè)可選參數(shù)的示例:

class Person {
    constructor(name)  {
        this.name = name
    }
}

function greet(person) {
    console.log(this.greeting.replace("$", person.name))
}

let english = {
    greeting: "Hello there, $"
}
let spanish = {
    greeting: "Hola $, ?cómo estás?"
}

let people = [new Person("Fernando"), new Person("Federico"), new Person("Felipe")]


people.forEach( greet, english)
people.forEach( greet, spanish)

通過(guò)重寫被調(diào)用函數(shù)greet的上下文,我可以在不影響其代碼的情況下更改其行為。

最后,顯示此方法也可以與異步代碼一起使用,下面是示例:

const fs = require("fs")

async function read(fname) {
    return new Promise( (resolve, reject) => {
        fs.readFile(fname, (err, content) => {
            if(err) return reject(err)
            resolve(content.toString())
        })
    })
}

let files = ['file1.json', 'file2.json']

files.forEach( async fname => {
    let fcontent = await read(fname)
    console.log(fcontent)
    console.log("-------")
})

以上是“javascript中3種for循環(huán)風(fēng)格的使用示例”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

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

AI