摘要:是上的一個欄目,主要講一些有趣的知識。分析下上述代碼中,變量是命令聲明的,在全局范圍內(nèi)都有效,所以全局只有一個變量。
后續(xù)內(nèi)容更新,請前往:個人博客,歡迎一起交流。
這是一道出自 HTTP 203 的 JS 題目。HTTP 203 是 Youtube 上的一個欄目,主要講一些有趣的知識。
原題目是這樣的:
for( let i = (setTimeout(()=>console.log(i), 2333), 0); i < 2; i++ ) { } // 問 2333 毫秒之后打印出什么
答案是 2333 毫秒后打印出 0。 為什么呢?
在開始分析題目之前,我們先來回顧幾個知識點:
for 語法for (語句 1; 語句 2; 語句 3) { 被執(zhí)行的代碼塊 }
語句 1(代碼塊)開始前執(zhí)行;
語句 2 定義運行循環(huán)(代碼塊)的條件;
語句 3 在循環(huán)(代碼塊)已被執(zhí)行之后執(zhí)行;
執(zhí)行的順序為:
1.第一次循環(huán),即初始化循環(huán)。
首先執(zhí)行語句1(一般為初始化語句),再執(zhí)行語句2(一般為條件判斷語句),判斷語句1是否符合語句2的條件,如果符合,則執(zhí)行代碼塊,否則,停止執(zhí)行,最后執(zhí)行語句3。
2.其他循環(huán):
首先判斷前一次語句3的執(zhí)行結(jié)果是否符合執(zhí)行語句2的條件,如果符合,繼續(xù)執(zhí)行代碼塊,否則停止執(zhí)行,最后執(zhí)行語句3。如此往復(fù),直到前一次語句3的執(zhí)行結(jié)果不滿足符合執(zhí)行語句2的條件。
總的來說,執(zhí)行順序是一致的,先執(zhí)行條件判斷(語句2),再執(zhí)行代碼塊,最后執(zhí)行語句3。如此往復(fù),區(qū)別在于條件判斷的對象,在第一次判斷時,是執(zhí)行語句1,初始化的對象,后續(xù)的判斷對象是執(zhí)行語句3的結(jié)果。
逗號表達式逗號表達式,因為原題目中就有使用逗號表達式let i = (setTimeout(()=>console.log(i), 2333), 0);。
逗號表達式的一般形式是:表達式1,表達式2,表達式3......表達式n。
逗號表達式的求解過程是:先計算表達式1的值,再計算表達式2的值,......一直計算到表達式n的值。最后整個逗號表達式的值是表達式n的值。 看下面幾個例子:
x=8*2, x*4 // 整個表達式的值為64,x的值為16 (x=8*2, x*4), x*2 // 整個表達式的值為32,x的值為16 x=(z=5, 5*2) // 整個表達式為賦值表達式,它的值為10,z的值為5,x的值為10 x=z=5, 5*2 // 整個表達式為逗號表達式,它的值為10,x和z的值都為5
逗號表達式用的地方不太多,一般情況是在給循環(huán)變量賦初值時才用得到。所以程序中并不是所有的逗號都要看成逗號運算符,尤其是在函數(shù)調(diào)用時,各個參數(shù)是用逗號隔開的,這時逗號就不是逗號運算符。
基礎(chǔ)知識回顧完畢,我們通過幾個簡單示例一步一步地逼近原題目:
示例一:基礎(chǔ)知識 for 循環(huán)for (var i = 0; i < 2; i++) { console.log(i); } // 打印什么
這個無需多說,答案輸出 0 1。
示例二:我們稍微改造下,將 log 放入 setTimeout 中for (var i = 0; i < 2; i++) { setTimeout(() => console.log(i)); } // 打印什么
答案輸出 2 2。分析下:
上述代碼中,變量 i 是 var 命令聲明的,在全局范圍內(nèi)都有效,所以全局只有一個變量 i。每一次循環(huán),變量 i 的值都會發(fā)生改變,而循環(huán)內(nèi)被賦給 setTimeout 內(nèi)部的 console.log(i),里面的 i 指向的就是全局的 i。也就是說,這里面所有的 i 指向的都是同一個 i,導(dǎo)致運行時輸出的是最后一輪的 i 的值,也就是 2。
for (let i = 0; i < 2; i++) { setTimeout(() => console.log(i)); } // 打印什么
答案輸出 0 1。分析下:
上述代碼中,變量 i 是 let 聲明的,當(dāng)前的 i 只在本輪循環(huán)有效,所以每一次循環(huán)的 i 其實都是一個新的變量,所以最后輸出的是0 1。你可能會問,如果每一輪循環(huán)的變量i都是重新聲明的,那它怎么知道上一輪循環(huán)的值,從而計算出本輪循環(huán)的值?這是因為 JavaScript 引擎內(nèi)部會記住上一輪循環(huán)的值,初始化本輪的變量i時,就在上一輪循環(huán)的基礎(chǔ)上進行計算。
for( let i = (setTimeout(()=>console.log(i), 2333), 0); // 語句1 i < 2; // 語句2 i++ // 語句3 ) { } // 問 2333 毫秒之后打印出什么
答案是 2333 毫秒后打印出 0。分析下:
上述題目中,變量 i 是 let 聲明的,當(dāng)前的 i 只在本輪循環(huán)有效,后面的表達式是逗號表達式,取最后一個值,即 i = 0,settimeout 在語句1,由于語句1只在第一次循環(huán)執(zhí)行,因此 settimeout 的作用域是第一次迭代的作用域,且只執(zhí)行一次。第一次迭代時 i = 0,所以答案是 2333 毫秒后打印出 0。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/97938.html
摘要:抽象語法樹大致流程生成然后通過類型斷言進行相應(yīng)的轉(zhuǎn)換反編譯工具全集小程序推薦逆向反編譯四大工具利器年支持的反編譯工具匯總原文 像軟件加密與解密一樣,javascript的混淆與解混淆同屬于同一個范疇。道高一尺,魔高一丈。沒有永恒的黑,也沒有永恒的白。一切都是資本市場驅(qū)動行為,現(xiàn)在都流行你能為人解決什么問題,這個概念。那么市場究竟能容納多少個能解決這種問題的利益者。JS沒有秘密。 其實本...
摘要:微信公眾號記錄截圖記錄截圖目前關(guān)于這塊算法與數(shù)據(jù)結(jié)構(gòu)的安排前。已攻略返回目錄目前已攻略篇文章。會根據(jù)題解以及留言內(nèi)容,進行補充,并添加上提供題解的小伙伴的昵稱和地址。本許可協(xié)議授權(quán)之外的使用權(quán)限可以從處獲得。 Create by jsliang on 2019-07-15 11:54:45 Recently revised in 2019-07-15 15:25:25 一 目錄 不...
摘要:題目描述刪除鏈表中等于給定值的所有節(jié)點。示例輸入輸出非遞歸解法思路遍歷鏈表,找出每個待刪除節(jié)點的前一個節(jié)點。特殊情況第一個節(jié)點就是待刪除節(jié)點時,要單獨操作。注意點當(dāng)輸入為時,按上面的思路刪除第一個節(jié)點,剩下的鏈表的頭節(jié)點又是待刪除節(jié)點。 題目描述 刪除鏈表中等于給定值 val 的所有節(jié)點。 示例 輸入: 1->2->6->3->4->5->6, val = 6輸出: 1->2->3->...
摘要:原題,跳轉(zhuǎn)到怎么通過獲取到請用實現(xiàn)看一分鐘之后,直覺告訴實現(xiàn)我不會。只知道,通過可以知道后來百度,問好朋友。真實意圖這道題的意思應(yīng)該是重定向后怎么獲取真實地址。實際做的就是在百度或者微博服務(wù)器上一個臨時重定向。 原題: $a=http://aaa.com/a,跳轉(zhuǎn)到$b=http://bbb.com/b.怎么通過$a獲取到$b,請用php實現(xiàn) 看一分鐘之后,直覺告訴PHP實現(xiàn)我不會。...
閱讀 3240·2021-11-22 09:34
閱讀 2871·2021-09-22 15:28
閱讀 882·2021-09-10 10:51
閱讀 1905·2019-08-30 14:22
閱讀 2399·2019-08-30 14:17
閱讀 2811·2019-08-30 11:01
閱讀 2376·2019-08-29 17:19
閱讀 3723·2019-08-29 13:17