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