日韩欧美人妻无码精品白浆,www.大香蕉久久网,狠狠的日狠狠的操,日本好好热在线观看

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

javascript篇:setTimeout遇上for循環(huán):為什么總是輸出5?如何正確輸出0-4?

freeflydom
2025年6月4日 11:39 本文熱度 687

今天咱們來聊聊一個(gè)經(jīng)典的面試題,也是很多新手容易踩坑的問題——在for循環(huán)中使用setTimeout。先看這段代碼:

for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

你以為它會(huì)輸出0,1,2,3,4?太天真了!實(shí)際輸出是五個(gè)5!這是為什么?又該如何解決?且聽我慢慢道來~

一、為什么會(huì)這樣?——作用域與閉包的"陷阱"

這個(gè)現(xiàn)象背后隱藏著JavaScript的兩個(gè)重要特性:

  1. var沒有塊級(jí)作用域:在for循環(huán)中用var聲明的i實(shí)際上是函數(shù)作用域(或全局作用域)的
  2. 異步執(zhí)行:setTimeout的回調(diào)函數(shù)會(huì)在循環(huán)結(jié)束后才執(zhí)行

具體執(zhí)行過程是這樣的:

  1. for循環(huán)瞬間執(zhí)行完畢(同步代碼),i從0增加到5(當(dāng)i=5時(shí)循環(huán)停止)
  2. 1秒后,5個(gè)setTimeout回調(diào)開始執(zhí)行
  3. 此時(shí)它們?cè)L問的都是同一個(gè)i,而i的值已經(jīng)是5了
  4. 所以輸出了5個(gè)5

二、解決方案1:使用IIFE創(chuàng)建閉包

for (var i = 0; i < 5; i++) {
  (function(j) {
    setTimeout(function() {
      console.log(j);
    }, 1000);
  })(i);
}

原理

  • 立即執(zhí)行函數(shù)(IIFE)為每次循環(huán)創(chuàng)建一個(gè)新作用域
  • 把當(dāng)前的i值作為參數(shù)j傳入并"凍結(jié)"住
  • 每個(gè)setTimeout回調(diào)訪問的都是自己閉包中的j

三、解決方案2:使用let塊級(jí)作用域(ES6推薦)

for (let i =  0; i < 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, 1000);
}

這是最優(yōu)雅的解決方案!

  • let有塊級(jí)作用域,每次循環(huán)都會(huì)創(chuàng)建一個(gè)新的i
  • 相當(dāng)于自動(dòng)為我們創(chuàng)建了閉包
  • 代碼簡潔直觀,沒有魔法

四、解決方案3:利用setTimeout的第三個(gè)參數(shù)

for (var i = 0; i < 5; i++) {
  setTimeout(function(j) {
    console.log(j);
  }, 1000, i);
}

小技巧

  • setTimeout可以接受多個(gè)參數(shù),第三個(gè)及以后的參數(shù)會(huì)作為回調(diào)函數(shù)的參數(shù)
  • 相當(dāng)于瀏覽器幫我們做了參數(shù)綁定

五、解決方案4:用bind提前綁定參數(shù)

for (var i = 0; i < 5; i++) {
  setTimeout(function(j) {
    console.log(j);
  }.bind(null, i), 1000);
}

原理

  • Function.prototype.bind可以提前綁定參數(shù)
  • 第一個(gè)參數(shù)是this(這里不需要所以傳null)
  • 后續(xù)參數(shù)會(huì)作為綁定函數(shù)的參數(shù)

六、深入理解:為什么let能解決問題?

let在for循環(huán)中的行為很特殊:

  1. 每次迭代都會(huì)創(chuàng)建一個(gè)新的詞法環(huán)境(可以理解為新的作用域)
  2. 新的i會(huì)在這個(gè)環(huán)境中初始化,值為上一次迭代結(jié)束時(shí)的值
  3. 相當(dāng)于自動(dòng)為我們創(chuàng)建了閉包

可以近似理解為:

// 偽代碼,幫助理解let的行為
{
  let i = 0;
  setTimeout(function() { console.log(i); }, 1000);
}
{
  let i = 1;
  setTimeout(function() { console.log(i); }, 1000);
}
// ...以此類推

七、實(shí)際開發(fā)中的建議

  1. 默認(rèn)使用let/const:告別var,擁抱塊級(jí)作用域
  2. 注意異步代碼的依賴關(guān)系:異步回調(diào)中使用循環(huán)變量時(shí)要特別小心
  3. 合理使用閉包:理解閉包的工作原理,但不要濫用
  4. 考慮代碼可讀性:有時(shí)候把異步邏輯提取成獨(dú)立函數(shù)會(huì)更清晰

八、舉一反三:類似的陷阱

這種問題不僅出現(xiàn)在setTimeout中,其他異步場(chǎng)景也會(huì)遇到:

// 事件監(jiān)聽中的類似問題
var buttons = document.querySelectorAll('button');
for (var i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', function() {
    console.log(i); // 總是輸出buttons.length
  });
}
// 解決方案同樣適用
for (let i = 0; i < buttons.length; i++) {
  buttons[i].addEventListener('click', function() {
    console.log(i); // 正確輸出對(duì)應(yīng)的索引
  });
}

九、總結(jié)

  1. 問題根源:var的作用域 + 異步執(zhí)行時(shí)機(jī)

  2. 解決方案

    • IIFE創(chuàng)建閉包(傳統(tǒng)方式)
    • 使用let(最推薦)
    • 利用setTimeout第三個(gè)參數(shù)
    • 使用bind綁定參數(shù)
  3. 最佳實(shí)踐:使用let/const避免這類問題

記住,在JavaScript中,同步代碼和異步代碼的執(zhí)行時(shí)機(jī)是需要特別關(guān)注的重點(diǎn)。理解閉包和作用域,就能輕松應(yīng)對(duì)這類問題。

轉(zhuǎn)自https://juejin.cn/post/7510587921788321832


該文章在 2025/6/4 11:48:19 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

AA大香蕉在线视频| 欧韩久久成人在线观看| 亚洲国产成a人v在线观看| 亚洲激情乱轮| 国产精品又大又长又粗| 丁香七月激情综合| 久久精品aⅴ无码中文字字幕不卡| 欧洲码和亚洲码的尺码专线在线播放 | 亚州12345免费视频| 婷婷一区二区天天干天| 亚洲乱亚洲乱| 欧美黄片试| 欧美日韩在线第十一页| 免费aV论理小说在线观看| 最近日韩成人| 日韩在线不卡免费福利基地| 午夜大片久久精品区| 天堂一区二区三区科技有限公| 激情啪啪啪欧美| 肏我…骚逼好想要视频| 国内偷拍在线播放| 日韩不卡2| 日B夫妻按摩性网| 成人精品福利网站| 曰本黄色录相| 欧美五十老熟妇| 插bb 视频| 中文字幕热女三级| 日本一道一区二区免费看| 久久久久XXXX视频| carporn成人在线承认| 后入视频精品在线| 欧美精品久久a V| 亚洲黄色影片麻豆网址| 、欧美日韩一级黄片| 大香蕉综合伊人| 又粗又大又爽视频| 久久久天堂麻豆| 亚洲:熟女综合| 66亚洲二卡男同| zaixianchaopen国产|