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

資訊專欄INFORMATION COLUMN

【進(jìn)階2-2期】JavaScript深入之從作用域鏈理解閉包

simpleapples / 1956人閱讀

摘要:使用上一篇文章的例子來(lái)說(shuō)明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問(wèn)外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。

(關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo))

本周正式開(kāi)始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。

本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃,點(diǎn)擊查看前端進(jìn)階的破冰之旅

如果覺(jué)得本系列不錯(cuò),歡迎轉(zhuǎn)發(fā),您的支持就是我堅(jiān)持的最大動(dòng)力。

本期推薦文章

JavaScript深入之閉包 ,由于微信不能訪問(wèn)外鏈,點(diǎn)擊閱讀原文就可以啦。

推薦理由

本文是從作用域鏈的角度來(lái)介紹閉包,不同于上文圖解作用域和閉包,本文語(yǔ)言簡(jiǎn)練,結(jié)構(gòu)清晰,相比上文要容易理解些。建議搭配上文一起閱讀。

閱讀筆記

紅寶書(shū)(p178)上對(duì)于閉包的定義:閉包是指有權(quán)訪問(wèn)另外一個(gè)函數(shù)作用域中的變量的函數(shù)

MDN 對(duì)閉包的定義為:閉包是指那些能夠訪問(wèn)自由變量的函數(shù)

其中自由變量,指在函數(shù)中使用的,但既不是函數(shù)參數(shù)arguments也不是函數(shù)的局部變量的變量,其實(shí)就是另外一個(gè)函數(shù)作用域中的變量。

使用上一篇文章的例子來(lái)說(shuō)明下自由變量:【進(jìn)階2-1期】深入淺出圖解作用域鏈和閉包

function getOuter(){
  var date = "1127";
  function getDate(str){
    console.log(str + date);  //訪問(wèn)外部的date
  }
  return getDate("今天是:"); //"今天是:1127"
}
getOuter();

其中date既不是參數(shù)arguments,也不是局部變量,所以date是自由變量。

總結(jié)起來(lái)就是下面兩點(diǎn):

1、是一個(gè)函數(shù)(比如,內(nèi)部函數(shù)從父函數(shù)中返回)

2、能訪問(wèn)上級(jí)函數(shù)作用域中的變量(哪怕上級(jí)函數(shù)上下文已經(jīng)銷毀)

分析

首先來(lái)一個(gè)簡(jiǎn)單的例子

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}

var foo = checkscope(); // foo指向函數(shù)f
foo();                    // 調(diào)用函數(shù)f()

簡(jiǎn)要的執(zhí)行過(guò)程如下:

進(jìn)入全局代碼,創(chuàng)建全局執(zhí)行上下文,全局執(zhí)行上下文壓入執(zhí)行上下文棧

全局執(zhí)行上下文初始化

執(zhí)行 checkscope 函數(shù),創(chuàng)建 checkscope 函數(shù)執(zhí)行上下文,checkscope 執(zhí)行上下文被壓入執(zhí)行上下文棧

checkscope 執(zhí)行上下文初始化,創(chuàng)建變量對(duì)象、作用域鏈、this等

checkscope 函數(shù)執(zhí)行完畢,checkscope 執(zhí)行上下文從執(zhí)行上下文棧中彈出

執(zhí)行 f 函數(shù),創(chuàng)建 f 函數(shù)執(zhí)行上下文,f 執(zhí)行上下文被壓入執(zhí)行上下文棧

f 執(zhí)行上下文初始化,創(chuàng)建變量對(duì)象、作用域鏈、this等

f 函數(shù)執(zhí)行完畢,f 函數(shù)上下文從執(zhí)行上下文棧中彈出

那么問(wèn)題來(lái)了, 函數(shù)f 執(zhí)行的時(shí)候,checkscope 函數(shù)上下文已經(jīng)被銷毀了,那函數(shù)f是如何獲取到scope變量的呢?

上文(【進(jìn)階2-1期】深入淺出圖解作用域鏈和閉包)介紹過(guò),函數(shù)f 執(zhí)行上下文維護(hù)了一個(gè)作用域鏈,會(huì)指向指向checkscope作用域,作用域鏈?zhǔn)且粋€(gè)數(shù)組,結(jié)構(gòu)如下。

fContext = {
    Scope: [AO, checkscopeContext.AO, globalContext.VO],
}

所以指向關(guān)系是當(dāng)前作用域 --> checkscope作用域--> 全局作用域,即使 checkscopeContext 被銷毀了,但是 JavaScript 依然會(huì)讓 checkscopeContext.AO(活動(dòng)對(duì)象) 活在內(nèi)存中,f 函數(shù)依然可以通過(guò) f 函數(shù)的作用域鏈找到它,這就是閉包實(shí)現(xiàn)的關(guān)鍵

概念

上面介紹的是實(shí)踐角度,其實(shí)閉包有很多種介紹,說(shuō)法不一。

湯姆大叔翻譯的關(guān)于閉包的文章中的定義,ECMAScript中,閉包指的是:

1、從理論角度:所有的函數(shù)。因?yàn)樗鼈兌荚趧?chuàng)建的時(shí)候就將上層上下文的數(shù)據(jù)保存起來(lái)了。哪怕是簡(jiǎn)單的全局變量也是如此,因?yàn)楹瘮?shù)中訪問(wèn)全局變量就相當(dāng)于是在訪問(wèn)自由變量,這個(gè)時(shí)候使用最外層的作用域。

2、從實(shí)踐角度:以下函數(shù)才算是閉包:

即使創(chuàng)建它的上下文已經(jīng)銷毀,它仍然存在(比如,內(nèi)部函數(shù)從父函數(shù)中返回)

在代碼中引用了自由變量

面試必刷題
var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();
data[1]();
data[2]();

如果知道閉包的,答案就很明顯了,都是3

循環(huán)結(jié)束后,全局執(zhí)行上下文的VO是

globalContext = {
    VO: {
        data: [...],
        i: 3
    }
}

執(zhí)行 data[0] 函數(shù)的時(shí)候,data[0] 函數(shù)的作用域鏈為:

data[0]Context = {
    Scope: [AO, globalContext.VO]
}

由于其自身沒(méi)有i變量,就會(huì)向上查找,所有從全局上下文查找到i為3,data[1] 和 data[2] 是一樣的。

解決辦法

改成閉包,方法就是data[i]返回一個(gè)函數(shù),并訪問(wèn)變量i

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = (function (i) {
      return function(){
          console.log(i);
      }
  })(i);
}

data[0]();    // 0
data[1]();    // 1
data[2]();    // 2

循環(huán)結(jié)束后的全局執(zhí)行上下文沒(méi)有變化。

執(zhí)行 data[0] 函數(shù)的時(shí)候,data[0] 函數(shù)的作用域鏈發(fā)生了改變:

data[0]Context = {
    Scope: [AO, 匿名函數(shù)Context.AO, globalContext.VO]
}

匿名函數(shù)執(zhí)行上下文的AO為:

匿名函數(shù)Context = {
    AO: {
        arguments: {
            0: 0,
            length: 1
        },
        i: 0
    }
}

因?yàn)殚]包執(zhí)行上下文中貯存了變量i,所以根據(jù)作用域鏈會(huì)在globalContext.VO中查找到變量i,并輸出0。

思考題

上面必刷題改動(dòng)一個(gè)地方,把for循環(huán)中的var i = 0,改成let i = 0。結(jié)果是什么,為什么???

var data = [];

for (let i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0]();
data[1]();
data[2]();
參考
JavaScript深入之閉包
往期文章查看

【進(jìn)階1-1期】理解JavaScript 中的執(zhí)行上下文和執(zhí)行棧

【進(jìn)階1-2期】JavaScript深入之執(zhí)行上下文棧和變量對(duì)象

【進(jìn)階1-3期】JavaScript深入之內(nèi)存空間詳細(xì)圖解

【進(jìn)階1-4期】JavaScript深入之帶你走進(jìn)內(nèi)存機(jī)制

【進(jìn)階1-5期】JavaScript深入之4類常見(jiàn)內(nèi)存泄漏及如何避免

【進(jìn)階2-1期】深入淺出圖解作用域鏈和閉包

每周計(jì)劃安排

每周面試重難點(diǎn)計(jì)劃如下,如有修改會(huì)通知大家。每周一期,為期半年,準(zhǔn)備明年跳槽的小伙伴們可以把本公眾號(hào)[置頂]()了。

【進(jìn)階1期】 調(diào)用堆棧

【進(jìn)階2期】 作用域閉包

【進(jìn)階3期】 this全面解析

【進(jìn)階4期】 深淺拷貝原理

【進(jìn)階5期】 原型Prototype

【進(jìn)階6期】 高階函數(shù)

【進(jìn)階7期】 事件機(jī)制

【進(jìn)階8期】 Event Loop原理

【進(jìn)階9期】 Promise原理

【進(jìn)階10期】Async/Await原理

【進(jìn)階11期】防抖/節(jié)流原理

【進(jìn)階12期】模塊化詳解

【進(jìn)階13期】ES6重難點(diǎn)

【進(jìn)階14期】計(jì)算機(jī)網(wǎng)絡(luò)概述

【進(jìn)階15期】瀏覽器渲染原理

【進(jìn)階16期】webpack配置

【進(jìn)階17期】webpack原理

【進(jìn)階18期】前端監(jiān)控

【進(jìn)階19期】跨域和安全

【進(jìn)階20期】性能優(yōu)化

【進(jìn)階21期】VirtualDom原理

【進(jìn)階22期】Diff算法

【進(jìn)階23期】MVVM雙向綁定

【進(jìn)階24期】Vuex原理

【進(jìn)階25期】Redux原理

【進(jìn)階26期】路由原理

【進(jìn)階27期】VueRouter源碼解析

【進(jìn)階28期】ReactRouter源碼解析

交流

本人Github鏈接如下,歡迎各位Star

http://github.com/yygmind/blog

我是木易楊,網(wǎng)易高級(jí)前端工程師,跟著我每周重點(diǎn)攻克一個(gè)前端面試重難點(diǎn)。接下來(lái)讓我?guī)阕哌M(jìn)高級(jí)前端的世界,在進(jìn)階的路上,共勉!

如果你想加群討論每期面試知識(shí)點(diǎn),公眾號(hào)回復(fù)[加群]即可

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

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

相關(guān)文章

  • 進(jìn)階2-3JavaScript深入閉包面試題解

    摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...

    alanoddsoff 評(píng)論0 收藏0
  • 進(jìn)階2-1深入淺出圖解作用域鏈閉包

    摘要:本期推薦文章從作用域鏈談閉包,由于微信不能訪問(wèn)外鏈,點(diǎn)擊閱讀原文就可以啦。推薦理由這是一篇譯文,深入淺出圖解作用域鏈,一步步深入介紹閉包。作用域鏈的頂端是全局對(duì)象,在全局環(huán)境中定義的變量就會(huì)綁定到全局對(duì)象中。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周開(kāi)始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第6天。 本...

    levius 評(píng)論0 收藏0
  • 進(jìn)階1-3JavaScript深入之內(nèi)存空間詳細(xì)圖解

    摘要:進(jìn)階期理解中的執(zhí)行上下文和執(zhí)行棧進(jìn)階期深入之執(zhí)行上下文棧和變量對(duì)象但是今天補(bǔ)充一個(gè)知識(shí)點(diǎn)某些情況下,調(diào)用堆棧中函數(shù)調(diào)用的數(shù)量超出了調(diào)用堆棧的實(shí)際大小,瀏覽器會(huì)拋出一個(gè)錯(cuò)誤終止運(yùn)行。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第3天。 本計(jì)劃一共28期,每期重點(diǎn)攻...

    coordinate35 評(píng)論0 收藏0
  • 進(jìn)階1-4JavaScript深入之帶你走進(jìn)內(nèi)存機(jī)制

    摘要:引擎對(duì)堆內(nèi)存中的對(duì)象進(jìn)行分代管理新生代存活周期較短的對(duì)象,如臨時(shí)變量字符串等。內(nèi)存泄漏對(duì)于持續(xù)運(yùn)行的服務(wù)進(jìn)程,必須及時(shí)釋放不再用到的內(nèi)存。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第4天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)劃...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 進(jìn)階1-5JavaScript深入之4類常見(jiàn)內(nèi)存泄漏及如何避免

    摘要:本期推薦文章類內(nèi)存泄漏及如何避免,由于微信不能訪問(wèn)外鏈,點(diǎn)擊閱讀原文就可以啦。四種常見(jiàn)的內(nèi)存泄漏劃重點(diǎn)這是個(gè)考點(diǎn)意外的全局變量未定義的變量會(huì)在全局對(duì)象創(chuàng)建一個(gè)新變量,如下。因?yàn)槔习姹镜氖菬o(wú)法檢測(cè)節(jié)點(diǎn)與代碼之間的循環(huán)引用,會(huì)導(dǎo)致內(nèi)存泄漏。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第一期,本周的主題...

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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<