国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端計(jì)劃——一道經(jīng)典的JavaScript問題(含閉包、事件輪詢、作用域等概念解釋)

EdwardUp / 2567人閱讀

摘要:作用域和作用域鏈關(guān)于作用域這里不做過多解釋,中根據(jù)作用域可分為全局變量和局部變量。好吧,不是這部分核心,核心是解釋的單線程和事件輪詢機(jī)制。這部分就涉及到閉包的理解了。

前言:這是一道很經(jīng)典的Js面試題,涉及到閉包、變量作用域、setTimeout等知識(shí),對(duì)于深入理解這些內(nèi)容很有幫助

題目描述
//問題描述:請(qǐng)寫出最終的輸出值,并解釋原因

var value1 = 0, value2 = 0, value3 = 0;
for ( var i = 1; i <= 3; i++) {
    var i2 = i;
    (function() {
        var i3 = i;
        setTimeout(function() {
            value1 += i;
            value2 += i2;
            value3 += i3;
        }, 1);
    })();
}
setTimeout(function() {
    console.log(value1, value2, value3);
}, 100);
//輸出結(jié)果:value1=12; value2=9; value3=6
題目解釋

首先,為了下面解釋這道題,我們先來補(bǔ)充一些預(yù)備知識(shí)(大神級(jí)人物可跳過這部分)

一、基礎(chǔ)知識(shí)補(bǔ)充與溫習(xí) 1、閉包和作用域

官方解釋:所謂“閉包”,指的是一個(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因而這些變量也是該表達(dá)式的一部分。

function a(){
    var i=0;
    function b(){
        alert(++i);
    }
    return b;
}
var c=a();
c();

方言版:當(dāng)函數(shù)a的內(nèi)部函數(shù)b被外部變量c引用時(shí),就形成了閉包

閉包的作用:我們知道,js里定義在函數(shù)內(nèi)部的是局部變量,外部是無法直接訪問的,而它的內(nèi)部函數(shù)可以訪問,那么內(nèi)部函數(shù)返回一個(gè)值,就相當(dāng)于類似在外部也能訪問局部變量。

閉包的特點(diǎn):為了使b中能夠訪問i的值,i不會(huì)被內(nèi)存回收,就實(shí)現(xiàn)了內(nèi)存常駐。對(duì)于理解這道題很重要。

閉包的缺點(diǎn):內(nèi)部閉包函數(shù)可以訪問外部函數(shù)的變量,所以外部函數(shù)的變量不能被釋放,如果閉包嵌套過多,會(huì)導(dǎo)致內(nèi)存占用大,出現(xiàn)內(nèi)存溢出。

作用域和作用域鏈:關(guān)于作用域這里不做過多解釋,js中根據(jù)作用域可分為全局變量和局部變量。而對(duì)于作用域鏈的簡(jiǎn)單理解,可以認(rèn)為當(dāng)一個(gè)函數(shù)創(chuàng)建之后,從它的執(zhí)行環(huán)境(當(dāng)前對(duì)象)一直到全局對(duì)象建立了一個(gè)鏈表,可用的變量都掛載在上面。而函數(shù)需要查找某個(gè)變量值時(shí),變回按照從當(dāng)前直到全局對(duì)象來進(jìn)行查找。

2、事件輪詢與setTimeout

簡(jiǎn)介:setTimeout是js中常見的一個(gè)函數(shù),屬于window下的方法(通常,大家會(huì)省略window)
語法:setTimeout(code,millisec) 參數(shù)一為代碼,參數(shù)二為毫秒數(shù)
作用:設(shè)定一個(gè)時(shí)間, 時(shí)間到了之后, 就會(huì)執(zhí)行一個(gè)指定的函數(shù)或表達(dá)式,且只執(zhí)行一次。

好吧,setTimeout不是這部分核心,核心是解釋js的單線程和事件輪詢機(jī)制。
我們知道,js是單線程的,也就是說所有的任務(wù)要排隊(duì)執(zhí)行。
在js中有同步和異步執(zhí)行——
同步執(zhí)行:是指前一個(gè)任務(wù)執(zhí)行完,然后下一個(gè)任務(wù)繼續(xù)執(zhí)行,都在主線程里。
異步執(zhí)行:則是把事情放進(jìn)“任務(wù)隊(duì)列”(或叫事件隊(duì)里),而不是在主線程中,它們通過事件輪詢(Event Loop)和回調(diào)來實(shí)現(xiàn)調(diào)入主線程執(zhí)行。
繼續(xù)回到setTimeout,語法里面的code就是異步執(zhí)行的部分。
關(guān)于setTimeout更詳細(xì)的內(nèi)容,可點(diǎn)擊這里學(xué)習(xí)setTimeout那些事
關(guān)于事件輪詢的學(xué)習(xí),請(qǐng)點(diǎn)擊這里理解事件輪詢

二、對(duì)習(xí)題的解答

上面都是些基礎(chǔ)知識(shí),接下來進(jìn)入正題。
首先,我們拿到題目,要注意到第一個(gè)setTimeout里面匿名函數(shù),這部分其實(shí)是放在for循環(huán)之后才會(huì)執(zhí)行的,因?yàn)樗且粋€(gè)異步執(zhí)行的函數(shù),被放到了事件隊(duì)列里最后執(zhí)行。而且,每次setTimeout里面的函數(shù)執(zhí)行時(shí)可以近似理解為是一次實(shí)例化。

value1
在計(jì)算value1時(shí),需要用到i,這里涉及到作用域鏈的知識(shí),最內(nèi)層的函數(shù)沒有i的值,它會(huì)沿著鏈?zhǔn)浇Y(jié)構(gòu)一直向上查找,最終發(fā)現(xiàn)i是for循環(huán)執(zhí)行之后的值。此時(shí),i的循環(huán)完成,最后一次i++之后,i已經(jīng)變成了4。這樣,setTimeout執(zhí)行3次實(shí)例化,每次i的值是不變的,最終值為value1=4+4+4=12。

value2

類似于value1,在執(zhí)行setTimeout里的函數(shù)時(shí),需要找到i2的值,最終我們找到的是for循環(huán)到第三次時(shí)i2=i=3。(i2不會(huì)等于4,因?yàn)榈阶詈笠淮蝘++之后,已經(jīng)不會(huì)再進(jìn)入循環(huán)體了)。所以類似上面,value2的值是3+3+3=9。

value3
這部分就涉及到閉包的理解了。在循環(huán)過程中,通過立即執(zhí)行函數(shù)創(chuàng)建了閉包,每次i3都會(huì)被賦予當(dāng)次循環(huán)時(shí)i的值并保存,i3的值依次為1,2,3,最終value3=1+2+3=6。

以上為個(gè)人解釋,如有錯(cuò)誤,還望各位指正。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/86759.html

相關(guān)文章

  • JavaScript系列(四) - 收藏集 - 掘金

    摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠矶际侵械闹鲗?dǎo)范式。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠矶际荍avaScript中的主導(dǎo)范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數(shù)式編程越來越多得受到開發(fā)者的青睞。函數(shù)式編程是一種強(qiáng)調(diào)減少對(duì)程序外部狀態(tài)產(chǎn)生改變的方式。因此,...

    cfanr 評(píng)論0 收藏0
  • 還擔(dān)心面試官問閉包?

    摘要:一言以蔽之,閉包,你就得掌握。當(dāng)函數(shù)記住并訪問所在的詞法作用域,閉包就產(chǎn)生了。所以閉包才會(huì)得以實(shí)現(xiàn)。從技術(shù)上講,這就是閉包。執(zhí)行后,他的內(nèi)部作用域并不會(huì)消失,函數(shù)依然保持有作用域的閉包。 網(wǎng)上總結(jié)閉包的文章已經(jīng)爛大街了,不敢說筆者這篇文章多么多么xxx,只是個(gè)人理解總結(jié)。各位看官瞅瞅就好,大神還希望多多指正。此篇文章總結(jié)與《JavaScript忍者秘籍》 《你不知道的JavaScri...

    tinyq 評(píng)論0 收藏0
  • JavaScript系列——JavaScript同步、異步、回調(diào)執(zhí)行順序之經(jīng)典閉包setTimeou

    摘要:同步異步回調(diào)傻傻分不清楚。分割線上面主要講了同步和回調(diào)執(zhí)行順序的問題,接著我就舉一個(gè)包含同步異步回調(diào)的例子。同步優(yōu)先回調(diào)內(nèi)部有個(gè),第二個(gè)是一個(gè)回調(diào)回調(diào)墊底。異步也,輪到回調(diào)的孩子們回調(diào),出來執(zhí)行了。 同步、異步、回調(diào)?傻傻分不清楚。 大家注意了,教大家一道口訣: 同步優(yōu)先、異步靠邊、回調(diào)墊底(讀起來不順) 用公式表達(dá)就是: 同步 => 異步 => 回調(diào) 這口訣有什么用呢?用來對(duì)付面試的...

    lewif 評(píng)論0 收藏0
  • JavaScript系列——JavaScript同步、異步、回調(diào)執(zhí)行順序之經(jīng)典閉包setTimeou

    摘要:同步異步回調(diào)傻傻分不清楚。分割線上面主要講了同步和回調(diào)執(zhí)行順序的問題,接著我就舉一個(gè)包含同步異步回調(diào)的例子。同步優(yōu)先回調(diào)內(nèi)部有個(gè),第二個(gè)是一個(gè)回調(diào)回調(diào)墊底。異步也,輪到回調(diào)的孩子們回調(diào),出來執(zhí)行了。 同步、異步、回調(diào)?傻傻分不清楚。 大家注意了,教大家一道口訣: 同步優(yōu)先、異步靠邊、回調(diào)墊底(讀起來不順) 用公式表達(dá)就是: 同步 => 異步 => 回調(diào) 這口訣有什么用呢?用來對(duì)付面試的...

    rockswang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<