1. 程式人生 > >一道經典面試題-----setTimeout(function(){},0)

一道經典面試題-----setTimeout(function(){},0)

一道經典面試題—–setTimeout(function(){},0)

先看題:

複製程式碼
1 for (var i = 0; i < 3; i++) {
2     setTimeout(function() {
3         console.log(i);
4     }, 0);
5     console.log(i);
6 }
複製程式碼

結果是:0 1 2 3 3 3
很多公司面試都愛出這道題,此題考察的知識點還是蠻多的。 都考察了那些知識點呢?
非同步、作用域、閉包。
我們來簡化此題:

1 setTimeout(function() {
2         console.log(1);
3 }, 0); 4 console.log(2); //先列印2,再列印1

因為是setTimeout是非同步的。
正確的理解setTimeout的方式(註冊事件): 有兩個引數,第一個引數是函式,第二引數是時間值。 呼叫setTimeout時,把函式引數,放到事件佇列中。等主程式執行完,再呼叫。

就像我們給按鈕繫結事件一樣:

1 btn.onclick = function() {
2         alert(1);
3 };

這麼寫完,會彈出1嗎。不會!!只是繫結事件而已! 必須等我們去觸發事件,比如去點選這個按鈕,才會彈出1。

setTimeout也是這樣的!只是繫結事件,等主程式執行完畢後,再去呼叫。

setTimeout的時間值是怎麼回事呢?

1 setTimeout(fn, 2000)

程式會不會報錯? 不會!而且還會準確得列印1。為什麼? 因為真正去執行console.log(i)這句程式碼時,var i = 1已經執行完畢了!

所以我們進行dom操作。可以先繫結事件,然後再去寫其他邏輯。

複製程式碼
1 window.onload = function() {
2         fn();
3 }
4 var fn = function() {
5         alert('hello')
6 };
複製程式碼

這麼寫,完全是可以的。因為非同步!

es5中是沒有塊級作用域的。

1 for
(var i = 0; i < 3; i++) {} 2 console.log(i); //3,也就說i可以在for迴圈體外訪問到。所以是沒有塊級作用域。

這回我們再來看看原題。
原題使用了for迴圈。迴圈的本質是幹嘛的? 是為了方便我們程式設計師,少寫重複程式碼。

原題等價於:

複製程式碼
 1 var i = 0;
 2 setTimeout(function() {
 3     console.log(i);
 4 }, 0);
 5 console.log(i);
 6 i++;
 7 setTimeout(function() {
 8     console.log(i);
 9 }, 0);
10 console.log(i);
11 i++;
12 setTimeout(function() {
13     console.log(i);
14 }, 0);
15 console.log(i);
16 i++;
複製程式碼

因為setTimeout是註冊事件。根據前面的討論,可以都放在後面。
原題又等價於如下的寫法:

複製程式碼
 1 var i = 0;
 2 console.log(i);
 3 i++;
 4 console.log(i);
 5 i++;
 6 console.log(i);
 7 i++;
 8 setTimeout(function() {
 9     console.log(i);
10 }, 0);
11 setTimeout(function() {
12     console.log(i);
13 }, 0);
14 setTimeout(function() {
15     console.log(i);
16 }, 0);  //彈出 0 1 2 3 3 3
複製程式碼

怎麼保證能彈出0,1, 2呢?

複製程式碼
1 for (var i = 0; i < 3; i++) {
2     setTimeout((function(i) {
3         return function() {
4             console.log(i);
5         };
6     })(i), 0);  //改為立即執行的函式
7     console.log(i);  
8 }
複製程式碼

相關推薦

一道經典試題-----setTimeout(function(){}0)

一道經典面試題—–setTimeout(function(){},0) 先看題: 1 for (var i = 0; i < 3; i++) { 2 setTimeout(function() { 3 console.log(i); 4 }, 0); 5 co

一道經典試題“I love china”的實現

來看一道經典的面試題,題目要求如下: 給定一個字串“I love china”,編寫程式完成以單詞為單位的逆序,如“china love i”,並要求不允許使用第三方變數儲存資料,但可以使用輔助指標變數等。 這道題主要考察字串的遍歷查詢以及分類處理,首先確定演算法,我們可以這樣處理字

MongoDB與Java 經典試題、課程好資源值得收藏

如何學習好Java、Spring Boot、如果學習好MongoDB?如何拿高薪?阿里巴巴雲棲社群整理了MongoDB與Java 經典面試題、課程,好資源值得收藏,陸續更新中。 【MongoDB面試題】[@徐雷frank]MongoDB如果有效應對單節點故障? https://yq.aliyun.com

一道Python試題:給出d = [True, False, True, False, True]請利用列表d只用一句話返回列表[0,2,4]

分享 忽略 class pytho 面試題 inf pos 如何 返回   前言:還是我,一個不知死活的小白,冒著生命危險去了一家有逼格的公司面試,去面試的路上就經歷了一番波折,公交車死等不來,最後差點誤了面試時間,這都不算什麽了,雖然對面試不抱什麽希望,但在技術面被虐成了

[經典試題][百度]數軸上從左到右有n各點a[0], a[1], ……,a[n -1]給定一根長度為L的繩子求繩子最多能覆蓋其中的幾個點。

題目 數軸上從左到右有n各點a[0], a[1], ……,a[n -1],給定一根長度為L的繩子,求繩子最多能覆蓋其中的幾個點。 思路一 遍歷所有區間跟繩子L比較。 i遍歷區間起點,j遍歷區間終

一道經典的Java試題:equals == 和hashcode()的區別

==: 對於基本型別是值比較,對於引用型別來說是引用比較。 /** * == 的比較 */ @Tes

Java面試常會被問到的經典試題學習或者求職你都要好好掌握

cookie 異常類 shu data 區別 origin 目的 tro jdk和jre Java現在的熱度雖然有所下降,但是,學Java的人依舊很多。。Java的崗位也是滲透很多。那麽,那些經典的Java知識點,你能看到問題就能說出一二三嗎?來一起看看。。 1.JDK和

基礎 | 36個經典試題來測一測您的Java基礎

到此為止,「Java基礎」系列的面試點已更新完畢,但關於Java NIO和Java8新特性之Lambda表示式部分的內容還停留在概述階段,不夠系統和深入,後續有機會再深入學習和更新。 在此,主要將Java基礎系列以面試題的形式進行彙總,用做面試前的準備與自測提綱。 公眾號後

想要年薪20萬先看會不會這28個企業運維崗經典試題

while循環 詭異 man 最大 冒號 esc 其他 主動模式和被動模式 程序 1、Linux如何掛載windows下的共享目錄? mount.cifs //IP地址/server /mnt/server -o user=administrator,password=1

遞迴求解走臺階問題一次可以走一步、兩步、三步、...、n步(經典試題——增強版走臺階)

1、問題描述       現在有一個臺階,一共有n階,你一次性可以走1步、2步、3步、......、n步。問:一共有多少種走法。 2、求解思路       第一步走1階:那麼這種情況下的走法數量和剩下n-1階的走法數量有關;

#套路非常深的一道Java試題 你中招了嗎?

在求職的過程中,技術測試是不可缺少的一部分,也是最關鍵的一部分,但是有些面試官喜歡去抽一些“套路”比較深的題目,看看面試者對於程式設計的理解是否深刻,這其中的題目中,也不乏有佼佼者! 如果有想學習java的程式設計師,可來我們的java學習扣qun:79979,2590免費送java的視訊教程噢

經典試題兩棧實現佇列以及兩佇列實現棧

經典面試題,兩個棧實現一個佇列,以及兩個佇列實現一個棧。 1、兩個棧實現一個佇列 (1)思路:兩個stack1,stack2,用stack1存放入佇列的資料(入隊操作);stack2負責出佇列的資料,若stack2中有資料就直接出棧,否則把stack1中的資料彈出到stack2中,這樣sta

【轉】漫畫:經典谷歌試題“扔雞蛋”看看你會做嗎?

 第二天 題目:扔雞蛋問題 有2個雞蛋,從100層樓上往下扔,以此來測試雞蛋的硬度。比如雞蛋在第9層沒有摔碎,在第10層摔碎了,那

20個「MySQL」經典試題答對轉dba 2w+「附答案」

經典題目 1、MySQL的複製原理以及流程 基本原理流程,3個執行緒以及之間的關聯; 2、MySQL中myisam與innodb的區別,至少5點 (1)、問5點不同; (2)、innodb引擎的4大特性 (3)、2者selectcount(*)哪個更快,為什麼

字串操作翻轉句子中單詞的順序--經典試題兩種解法

題目:輸入一個英文句子,翻轉句子中單詞的順序,但單詞內字元的順序不變。 句子中單詞以空格符隔開。為簡單起見,標點符號和普通字母一樣處理。 例如輸入“I am a student.”,則輸出“stud

一道Java試題 讀取一篇英文文章輸出其中出現單詞的次數最多的5個,寫java函式

package com.test.string; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayLis

2018年web前端經典試題總結你能做對幾個?

對程式設計師小哥哥小姐姐來說,很多時候差的不是技術,卻過不了面試那一關。這時候我們就需要總結分析一下面試題目了,揣摩公司與hr的心理及需求,有時候我們忽略的小問題就是決定能不能拿到offer的重要因素,希望大家都可以找到自己心儀的工作,從容應對面試~ 1、webpack怎麼引入第三方的庫?

測試用例設計經典試題——電梯杯子桌子洗衣機

         首先說明的是,遇到這樣的測試題目,首先應該反問面試官,需求是什麼樣的,比如是測什麼樣的杯子。        因為設計測試用例的規則應該是根據需求分析文件設計用例,客戶需求什麼,就測試什麼。但是在沒有需求分析文件的前提下, 來設計測試用例,可以考查一個測試人

一道JS試題所引發的"血案"透過現象尋本質再從本質看現象

覺得本人寫的不算很爛的話,可以登入關注一下我的GitHub部落格,新手寫東西寫的不好之處,還望見諒,畢竟水平有限,寫東西只為交流提高,一起學習,還望大神多加指點,指出紕漏,和提出寶貴的意見,部落格會堅持寫下去。 今天同學去面試,做了兩道面試題,全部做錯了,發過來給我看,我一眼就看出來了,因為這種題我做過,至