從來都沒有理解JavaScript閉包 今天非把你教會(huì)不可! 看這一篇就夠了,全程大白話!

作者: 極客小俊
公眾號: 同名

closure_logo.png

從來都沒有理解JavaScript閉包? 今天非把你教會(huì)不可! 看這一篇就夠了,全程大白話!

前言

這么多年了哲银,你是否還在討論javascript閉包呢? 閉包這個(gè)概念幾乎也是任何前端面試官都會(huì)必考的問題!

并且理解javascript閉包也是邁向高級前端開發(fā)工程師的必經(jīng)之路!

也只有理解了閉包原理和運(yùn)行機(jī)制才能寫出更為安全和優(yōu)雅的javascript代碼

那么你是否學(xué)習(xí)javascript很久了但閉包還沒有搞懂呢? ?? 閉包很晦澀難懂嗎? 或許你把閉包這個(gè)概念想象得太過神奇! 今天就來揭秘javascript閉包 一個(gè)前端開發(fā)經(jīng)久不衰的話題!

學(xué)習(xí)條件

這里我也特別說明一下閉包其實(shí)牽扯的東西還是有點(diǎn)多,涉及到以下JS知識點(diǎn):

  1. 函數(shù)的執(zhí)行上下文環(huán)境(Execution context of function)
  2. 變量對象(Variable object)
  3. 活動(dòng)對象(Active object)
  4. 作用域(scope)
  5. 作用域鏈(scope chain)

那么如果你對以上所涉及到的知識點(diǎn)還沒有清楚,那么建議補(bǔ)一下析校,我以后也會(huì)慢慢提及, 否則理解閉包就會(huì)出現(xiàn)歧義!

到底什么是閉包?

概述

閉包比較書面化的解釋是: 一個(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式,并且通常是一個(gè)函數(shù), 而這些變量也是該表達(dá)式的一部分礁哄。我想如果你是一個(gè)零基礎(chǔ)的小白, 那么估計(jì)不出意外的話應(yīng)該完全不能理解這句話!?? 沒關(guān)系想搞懂我們接著往下看...

那么我們首先來看一段JS代碼

//函數(shù)定義
function outerTest() {
    var num = 0;
    function innerTest() {
        ++num
        console.log(num);
    }
    return innerTest;
}

//調(diào)用
var fn1 = outerTest();
fn1();
fn1();
fn1();

運(yùn)行結(jié)果

1.png

以上就是一個(gè)閉包的經(jīng)典案例, 我們慢慢來分析!

其實(shí)你會(huì)發(fā)現(xiàn)以上這段JS代碼有兩個(gè)特點(diǎn):

1长酗、innerTest函數(shù)嵌套在outerTest函數(shù)的內(nèi)部

2、outerTest函數(shù)的返回值就是innerTest函數(shù)

那么有人就會(huì)說函數(shù)嵌套函數(shù)就是閉包 其實(shí)這樣子說是不嚴(yán)謹(jǐn)?shù)?

原理分析

接著之前的那一段JS代碼 我們來看一張圖

2.jpg

代碼分析

當(dāng)在執(zhí)行完var fn1 = outerTest();之后桐绒,變量fn1實(shí)際上是指向了函數(shù)innerTest夺脾,

那么接下來如果再執(zhí)行fn1()就會(huì)改變num變量的值, 當(dāng)然這個(gè)過程通常懂一點(diǎn)程序執(zhí)行流程也可以分析出來!

關(guān)鍵不同的是之后繼續(xù)執(zhí)行fn1()輸出的卻是num變量累加之后的結(jié)果! 你肯定想知道為什么會(huì)累加!對吧!??

首先因?yàn)?code>函數(shù)innerTest引用了函數(shù)outerTest內(nèi)部的變量或者數(shù)據(jù),再然后重點(diǎn)來了:

當(dāng)一個(gè)局部函數(shù)或匿名函數(shù)被定義的時(shí)候,那么它的作用域鏈也會(huì)被初始化,并且雖然有的時(shí)候局部函數(shù)即便是沒有被調(diào)用之拨,但是它會(huì)執(zhí)行一個(gè)動(dòng)作: 就是復(fù)制一份父函數(shù)的作用域鏈, 并且再將此作用域鏈的第0位插入該未調(diào)用函數(shù)的變量對象,等到該函數(shù)被調(diào)用了就激活為活動(dòng)對象

如果實(shí)在你還無法理解這里的【作用域鏈】咧叭,那么你可以理解為是一種描述路徑的術(shù)語, 沿著該路徑可以找到需要的變量值!

再次回到閉包的概念上來, 也就是當(dāng)一個(gè)子函數(shù)引用了父級函數(shù)的某個(gè)變量或數(shù)據(jù)蚀乔,那么 閉包其實(shí)就產(chǎn)生了

并且這個(gè)變量或數(shù)據(jù)的生命周期始終能保持使用,就能間接保持原構(gòu)父級函數(shù) 在內(nèi)存中的變量對象不會(huì)消失

所以盡管outerTest()函數(shù)已經(jīng)調(diào)用結(jié)束, 但是子函數(shù)卻始終能引用到該父級函數(shù)中的變量的值菲茬,并且該變量值只能通這種方法來訪問!

即使再次調(diào)用相同的outerTest()函數(shù)吉挣,但只會(huì)生成相對應(yīng)的變量對象,新的變量對象只是對應(yīng)新的值, 和上次那次調(diào)用的是各自獨(dú)立的!

如圖

3.png

簡而言之 在嵌套在父級函數(shù)內(nèi)部的子函數(shù)被定義時(shí),并且也引用了父級函數(shù)的數(shù)據(jù)時(shí)就產(chǎn)生了閉包

需要重點(diǎn)注意的是: 一個(gè)閉包內(nèi)對變量的修改婉弹,不會(huì)影響到另外一個(gè)閉包中的變量

以上案例就是在outerTest函數(shù)執(zhí)行完并返回后睬魂,閉包使得JS中的的垃圾回收機(jī)制GC(Garbage collection)不會(huì)收回outerTest函數(shù)所占用的資源,這里指的資源是它的變量對象, 因?yàn)?code>outerTest函數(shù)的內(nèi)部函數(shù)innerTest的執(zhí)行一直需要依賴outerTest函數(shù)中的變量或者其他數(shù)據(jù)镀赌。這就是對閉包產(chǎn)生和特性最直白通俗的描述!

那么現(xiàn)在回過頭來再次理解為什么每次調(diào)用fn1()函數(shù) 變量num會(huì)累加? 看下面這張圖!

如圖

4.jpg

因?yàn)橛捎?code>閉包的存在使得函數(shù)outerTest返回后氯哮,函數(shù)outerTest中的num變量其實(shí)始終存在與內(nèi)存中,這樣每次執(zhí)行fn1()佩脊,都會(huì)找到內(nèi)存中與之對應(yīng)outerTest函數(shù)變量對象num變量進(jìn)行累加1后,輸出num的值

閉包具體步驟總結(jié)
  1. 當(dāng)執(zhí)行函數(shù)outerTest的時(shí)候蛙粘,outerTest函數(shù)會(huì)進(jìn)入相應(yīng)的執(zhí)行上下文環(huán)境!
  2. 在創(chuàng)建函數(shù)outerTest執(zhí)行環(huán)境的過程中,首先會(huì)為函數(shù)outerTest添加一個(gè)scope屬性威彰,即函數(shù)outerTest的作用域出牧,其值就為函數(shù)outerTest中的作用域鏈scope chain
  3. 然后執(zhí)行環(huán)境會(huì)創(chuàng)建一個(gè)活動(dòng)對象(activation object)⌒危活動(dòng)對象也是當(dāng)前被調(diào)用這個(gè)函數(shù)所擁有的一個(gè)對象舔痕,它是用來保存數(shù)據(jù)的, 它不能通過JS代碼直接訪問, (如果你實(shí)在理解不了可以想象成一個(gè)抽象的對象)
  4. 創(chuàng)建完活動(dòng)對象后,把該活動(dòng)對象添加到outerTest函數(shù)作用域鏈中的最頂端,也就是圖中的第0位,此時(shí)outerTest函數(shù)作用域鏈包含了兩個(gè)對象:outerTest函數(shù)活動(dòng)對象全局window變量對象也就是圖中藍(lán)色和綠色兩個(gè)對象
  5. 然后在outerTest函數(shù)活動(dòng)對象上添加一個(gè)arguments屬性豹缀,它保存著調(diào)用outerTest函數(shù)時(shí)所傳遞的實(shí)際參數(shù)伯复,當(dāng)然我們這里并沒有傳遞任何參數(shù)進(jìn)來!
  6. 再然后把所有outerTest函數(shù)形參和內(nèi)部的innerTest函數(shù)、以及num變量這些數(shù)據(jù)的引用也添加到outerTest函數(shù)活動(dòng)對象上邢笙。
  7. 此時(shí)完成了函數(shù)innerTest的定義啸如,因此如同第3步,函數(shù)innerTest作用域鏈以及innerTest函數(shù)的變量對象跟之前outerTest函數(shù)一樣被初始化了, 那么到這里整個(gè)outerTest函數(shù)從定義到執(zhí)行的步驟就完成了!
  8. 然后在外部 outerTest函數(shù)返回innerTest函數(shù)命名為fn1引用變量氮惯,又因?yàn)?code>innerTest函數(shù)的作用域鏈包含了對outerTest函數(shù)變量對象的引用叮雳,注意:此時(shí)outerTest函數(shù)已經(jīng)調(diào)用結(jié)束,活動(dòng)對象也變成了內(nèi)存中滯留的變量對象,那么innerTest函數(shù)可以訪問到outerTest函數(shù)中定義的所有變量和函數(shù), 并且innerTest函數(shù)被外部的fn1所引用,函數(shù)innerTest又依賴函數(shù)outerTest妇汗,因此函數(shù)outerTest變量對象在返回后不會(huì)被JS垃圾回收機(jī)制GC(Garbage collection)銷毀帘不。

所以當(dāng)fn1執(zhí)行也相當(dāng)于在執(zhí)行函數(shù)innerTest時(shí)候也會(huì)像以上步驟一樣。因此執(zhí)行時(shí)innerTest函數(shù)作用域鏈包中含了3個(gè)對象:innerTest函數(shù)活動(dòng)對象杨箭、outerTest函數(shù)變量對象全局window變量對象, 也就是圖中藍(lán)色+綠色+紫色三個(gè)對象, 如果你覺得上圖看不清楚那么就看下面這張圖!

如圖

6.jpg

當(dāng)在innerTest函數(shù)中訪問一個(gè)變量時(shí),搜索順序是先搜索自身的活動(dòng)對象如果存在則返回

注意: 如果函數(shù)innerTest存在prototype原型對象寞焙,則在查找完自身的活動(dòng)對象后, 會(huì)先查找自身的原型對象

如果不存在將繼續(xù)搜索滯留在內(nèi)存中outerTest函數(shù)變量對象,依次查找直到找到為止, 這就是JS中的數(shù)據(jù)查找機(jī)制 ,當(dāng)然如果整個(gè)作用域鏈上都無法找到,則返回undefined

我們在理解閉包的時(shí)候 重點(diǎn)也是在作用域鏈這個(gè)環(huán)節(jié)容易出錯(cuò), 要知道函數(shù)的定義與執(zhí)行的區(qū)別捣郊。

函數(shù)作用域是在函數(shù)定義時(shí)就已經(jīng)確定辽狈,而不是在執(zhí)行的時(shí)候確定, 這里引出了一個(gè)概念詞法作用域

舉個(gè)栗子??

function outer(num) { 
  function inner() {
      return num; 
   }
  return inner;
}
var fn1 = outer(1);
console.log(fn1());

我們假設(shè)函數(shù)fn1作用域是在執(zhí)行時(shí),也就是console.log(fn1())確定的,那么此時(shí)fn1的作用域鏈?zhǔn)侨缦拢?/p>

函數(shù)fn1的活動(dòng)對象->console.log的活動(dòng)對象->window對象模她,如果假設(shè)成立稻艰,那么輸出值就必然是undefined

另一種假設(shè)也就是函數(shù)fn1的作用域是在定義時(shí)確定的懂牧,就是說fn1指向的inner函數(shù)在定義的時(shí)候就已經(jīng)確定了作用域侈净。那么在執(zhí)行的時(shí)候,函數(shù)fn1的作用域鏈為如下:

函數(shù)fn1的活動(dòng)對象->函數(shù)outer的變量對象->window對象僧凤,如果假設(shè)成立畜侦,那么輸出值也就是1。

所以運(yùn)行結(jié)果最終為1躯保,說明了第2種假設(shè)是正確的旋膳,也就證明了函數(shù)的作用域確實(shí)是在定義這個(gè)函數(shù)的時(shí)候就已經(jīng)確定了這個(gè)說法!

有人又會(huì)問如果我們不返回outerTest函數(shù)行不行呢? 答案肯定是不行的

因?yàn)?code>outerTest函數(shù)執(zhí)行完后,innerTest函數(shù)沒有被返回給外界途事,只是被outerTest函數(shù)所使用

因此函數(shù)outerTest函數(shù)innerTest互相使用, 但又不被外界使用验懊,那么函數(shù)outerTest執(zhí)行完畢之后就會(huì)被GC(Garbage collection)垃圾回收機(jī)制回收, 那么outerTest函數(shù)執(zhí)行上下文環(huán)境也會(huì)被彈出call Stack, 內(nèi)存中也不會(huì)在有outerTest函數(shù)所對應(yīng)的變量對象了, 自然也無法繼續(xù)保存值了!

5.jpg
閉包的應(yīng)用場景

應(yīng)用場景1 代碼模塊化

閉包的應(yīng)用場景主要是用于模塊化

閉包可以一定程度上保護(hù)函數(shù)內(nèi)的變量安全。

還是剛才的案例舉例!

outerTest函數(shù)中的num變量只有innerTest函數(shù)才能訪問尸变,而無法通過其他途徑訪問到义图,因此保護(hù)了num變量的安全性, 所以閉包模塊化基本可以解決函數(shù)污染變量隨意被修改問題!

比如說Java、php等語言中有支持將方法聲明為私有召烂,它們只能被同一個(gè)類中的其它方法所調(diào)用碱工。

js是沒有這種原生支持的,但我們可以使用閉包模擬私有方法奏夫。

私有方法不僅僅有利于限制對代碼的訪問權(quán)限, 還提供了管理全局命名空間的強(qiáng)大能力怕篷,避免非核心的方法弄亂了代碼的公共接口部分。

舉個(gè)栗子??

var Counter = (function() {
 var privateCounter = 0;
 function changeBy(val) {
      privateCounter += val;
 }
 return {
   increment: function() {
     changeBy(1);
   },
   decrement: function() {
     changeBy(-1);
   },
   value: function() {
     return privateCounter;
   }
 }
})();

console.log(Counter.value()); /* 輸出 0 */
Counter.increment();  //執(zhí)行遞增
Counter.increment();  //執(zhí)行遞增
console.log(Counter.value()); /* 輸出 2 */
Counter.decrement();   //執(zhí)行遞減  
console.log(Counter.value()); /* 輸出 1 */

如圖

7.png

以上案例表現(xiàn)了如何使用閉包來定義公共函數(shù)酗昼,并讓它可以訪問私有函數(shù)變量

IIFE匿名函數(shù)包含兩個(gè)私有數(shù)據(jù):名為 privateCounter 變量changeBy函數(shù), 而這兩項(xiàng)都無法在這個(gè)匿名函數(shù)外部直接訪問廊谓。必須通過匿名函數(shù)返回的三個(gè)公共函數(shù)接口來進(jìn)行訪問!

increment()、decrement()麻削、value()這三個(gè)公共函數(shù)是共享同一個(gè)作用域執(zhí)行上下文環(huán)境的變量對象, 也就是閉包也多虧 js作用域蒸痹,它們都可以訪問 privateCounter變量changeBy函數(shù)

應(yīng)用場景2 在內(nèi)存中保持變量數(shù)據(jù)一直不丟失!

還是以最開始的例子, 由于閉包的影響碟婆,函數(shù)outerTestnum變量會(huì)一直存在于內(nèi)存中电抚,因此每次執(zhí)行外部的fn1()時(shí),都會(huì)給num變量進(jìn)行累加!

所以每累加一次也就是每調(diào)用一次fn1() 就會(huì)去內(nèi)存中一層層尋找outerTest函數(shù)變量對象里面的num進(jìn)行累加!

現(xiàn)在完全明白了閉包了吧!??

如果你真的理解了閉包竖共,那么下面這個(gè)案例就很容易去推理了蝙叛,也非常經(jīng)典 就是在事件循環(huán)中如何保留每一次循環(huán)的索引值!

代碼栗子

html代碼

<button>Button0</button>
<button>Button1</button>
<button>Button2</button>
<button>Button3</button>
<button>Button4</button>

js代碼

window.onload=function(){
   var btns = document.getElementsByTagName('button');
   for(var i = 0,len = btns.length; i < len; i++) {
       btns[i].onclick = function() {
           console.log(i);
       }
   }
}

分析

通過執(zhí)行該段代碼,其實(shí)你會(huì)發(fā)現(xiàn)不論點(diǎn)擊哪個(gè)button按鈕 公给,均輸出5,

如圖

8.gif

這是很多初學(xué)者 或者還沒有完全理解閉包的朋友心中的困惑! ?? 那今天就要跟你解開這個(gè)困惑了!

首先你要明白一點(diǎn), onclick事件是被異步觸發(fā)的借帘,也就是等著用戶事件被觸發(fā)時(shí)蜘渣,for循環(huán)其實(shí)早已結(jié)束!

此時(shí)變量 i 的值已經(jīng)是5 所以當(dāng)onlick事件函數(shù)順著作用域鏈從內(nèi)向外查找變量 i時(shí),找到的值總是 5

也就是這個(gè)變量i已經(jīng)在外層的變量對象中一直保存的都是最終值!

如果你想要每次都打印出所 對應(yīng)的索引號 這里就要使用到閉包了!

修改js代碼如下形式

window.onload=function(){
    var btns = document.getElementsByTagName('button');
    for(var i = 0, len = btns.length; i < len; i++) {
        (function(i) {
            btns[i].onclick = function() {
                console.log(i);
            }
        }(i))
    }
}

或者

window.onload=function(){
    var btns = document.getElementsByTagName('button');
    for(var i = 0, len = btns.length; i < len; i++) {
        function test(index){
            btns[index].onclick = function() {
                console.log(index);
            }
        }
        test(i)
    }
}

這樣一來每次循環(huán)的變量i值都被封閉起來肺然,這樣在事件函數(shù)執(zhí)行時(shí)蔫缸,會(huì)查找定義時(shí)的作用域鏈,這個(gè)作用域鏈里的變量i值是在每次循環(huán)中都被保留在對應(yīng)的變量對象中际起,因此點(diǎn)擊不同的button按鈕會(huì)輸出不同的變量i

如圖

9.gif
閉包的缺陷

如果不是某些特定業(yè)務(wù)需求下, 盡量避免使用閉包拾碌,因?yàn)?code>閉包在處理速度和內(nèi)存消耗方面對腳本性能具有負(fù)面影響, 其會(huì)根據(jù)閉包數(shù)量的多少而在內(nèi)存中創(chuàng)建更多的變量對象, 最終可能會(huì)導(dǎo)致內(nèi)存溢出 等情況!

當(dāng)然通常最簡單的解決辦法就是: 解除對引用變量函數(shù)的使用

引用變量函數(shù) = null; 

我們可以將引用變量的值將其設(shè)置為null即可,js垃圾回收將會(huì)將其清除, 釋放內(nèi)存資源!

總結(jié)閉包

1、當(dāng)內(nèi)部函數(shù) 在定義它的作用域的外部被引用(使用)時(shí),就創(chuàng)建了該內(nèi)部函數(shù)的閉包 ,如果內(nèi)部函數(shù)引用了位于父級函數(shù)的變量或者其他數(shù)據(jù)時(shí),當(dāng)父級函數(shù)調(diào)用完畢后,這些變量數(shù)據(jù)在內(nèi)存不會(huì)被GC(Garbage collection)釋放,因?yàn)?code>閉包它們被一直引用著!否則兩者沒有交互就不會(huì)長久存在于內(nèi)存中,所以在Chrome中的debug找不到閉包

2街望、通過調(diào)用閉包的內(nèi)部函數(shù)獲取到閉包的成員變量:
在閉包中返回該函數(shù)校翔,在外部接收該函數(shù)并執(zhí)行就能獲取閉包的成員變量。
原因是因?yàn)?code>詞法作用域灾前,也就是函數(shù)的作用域是其聲明的作用域而不是執(zhí)行調(diào)用時(shí)的作用域防症。

如果我的博客對你有幫助、如果你喜歡我的博客內(nèi)容哎甲,請 “點(diǎn)贊” “評論” “收藏” 一鍵三連哦蔫敲!


如果以上內(nèi)容有任何錯(cuò)誤或者不準(zhǔn)確的地方,歡迎在下面 ?? 留個(gè)言指出炭玫、或者你有更好的想法奈嘿,歡迎一起交流學(xué)習(xí)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市础嫡,隨后出現(xiàn)的幾起案子指么,更是在濱河造成了極大的恐慌,老刑警劉巖榴鼎,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伯诬,死亡現(xiàn)場離奇詭異,居然都是意外死亡巫财,警方通過查閱死者的電腦和手機(jī)盗似,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來平项,“玉大人赫舒,你說我怎么就攤上這事∶銎埃” “怎么了接癌?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扣讼。 經(jīng)常有香客問我缺猛,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任荔燎,我火速辦了婚禮耻姥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘有咨。我一直安慰自己琐簇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布座享。 她就那樣靜靜地躺著婉商,像睡著了一般。 火紅的嫁衣襯著肌膚如雪征讲。 梳的紋絲不亂的頭發(fā)上据某,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機(jī)與錄音诗箍,去河邊找鬼。 笑死挽唉,一個(gè)胖子當(dāng)著我的面吹牛滤祖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓶籽,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼匠童,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了塑顺?” 一聲冷哼從身側(cè)響起汤求,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎严拒,沒想到半個(gè)月后扬绪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裤唠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年挤牛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片种蘸。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡墓赴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出航瞭,到底是詐尸還是另有隱情诫硕,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布刊侯,位于F島的核電站章办,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纲菌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一挠日、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翰舌,春花似錦嚣潜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至庇麦,卻和暖如春计技,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背山橄。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工垮媒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人航棱。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓睡雇,卻偏偏與公主長得像,于是被迫代替她去往敵國和親饮醇。 傳聞我的和親對象是個(gè)殘疾皇子它抱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1祠墅、什么是閉包侮穿? 閉包是指有權(quán)訪問另外一個(gè)函數(shù)作用域中的變量的函數(shù)《叮可以理解為(能夠讀取另一個(gè)函數(shù)作用域的變量的函...
    為光pig閱讀 798評論 0 0
  • 閉包是js開發(fā)慣用的技巧撮珠,什么是閉包?閉包指的是:能夠訪問另一個(gè)函數(shù)作用域的變量的函數(shù)金矛。清晰的講:閉包就是一個(gè)函數(shù)...
    下一站深圳閱讀 115,938評論 35 91
  • 前言 面試問題: 說一下對變量提升的理解 說明this的幾種不同的使用場景 創(chuàng)建10個(gè) 標(biāo)簽芯急,點(diǎn)擊的時(shí)候彈出來對應(yīng)...
    陳觀齊閱讀 238評論 0 1
  • 閉包(Closure)是前端開發(fā)者經(jīng)常會(huì)聽到的一個(gè)概念,也是我們在求職面試中經(jīng)常會(huì)遇到的題目之一驶俊。透過表象去理解閉...
    淘淘笙悅閱讀 1,572評論 0 12
  • 一娶耍、介紹 作用域鏈就是根據(jù)在內(nèi)部函數(shù)可以訪問外部函數(shù)變量的這種機(jī)制,用鏈?zhǔn)讲檎覜Q定哪些數(shù)據(jù)能被內(nèi)部函數(shù)訪問饼酿。 想要...
    走著別浪閱讀 384評論 2 6