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

資訊專欄INFORMATION COLUMN

重學(xué)前端學(xué)習(xí)筆記(十八)--JavaScript的閉包和執(zhí)行上下文

caikeal / 1430人閱讀

摘要:申明與賦值立即執(zhí)行的函數(shù)表達(dá)式,通過創(chuàng)建一個函數(shù),并且立即執(zhí)行,來構(gòu)造一個新的域,從而控制的范圍。函數(shù)接受一個的形參,該參數(shù)是一個對象引用,并執(zhí)行了。在最新的標(biāo)準(zhǔn)中,引入了一個新概念。

筆記說明
重學(xué)前端是程劭非(winter)【前手機淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些要點筆記以及感悟,完整的可以加入winter的專欄學(xué)習(xí)【原文有winter的語音】,如有侵權(quán)請聯(lián)系我,郵箱:kaimo313@foxmail.com。
一、函數(shù)執(zhí)行過程相關(guān)知識

二、閉包(closure)
閉包其實只是一個綁定了執(zhí)行環(huán)境的函數(shù),閉包與普通函數(shù)的區(qū)別是,它攜帶了執(zhí)行的環(huán)境,就像人在外星中需要自帶吸氧的裝備一樣,這個函數(shù)也帶有在程序中生存的環(huán)境。
2.1、古典的閉包

環(huán)境部分

環(huán)境

標(biāo)識符列表

表達(dá)式部分

2.2、JavaScript 中閉包

環(huán)境部分

環(huán)境:函數(shù)的詞法環(huán)境(執(zhí)行上下文的一部分)

標(biāo)識符列表:函數(shù)中用到的未申明的變量

表達(dá)式部分:函數(shù)體

三、執(zhí)行上下文(執(zhí)行的基礎(chǔ)設(shè)施)
定義:JavaScript 標(biāo)準(zhǔn)把一段代碼(包括函數(shù)),執(zhí)行所需的所有信息定義為執(zhí)行上下文。
3.1、在 ES3

scope:作用域,也常常被叫做作用域鏈

variable object:變量對象,用于存儲變量的對象

this value:this 值

3.2、在 ES5

lexical environment:詞法環(huán)境,當(dāng)獲取變量時使用

variable environment:變量環(huán)境,當(dāng)聲明變量時使用

this value:this 值

3.3、在 ES2018

lexical environment:詞法環(huán)境,當(dāng)獲取變量或者 this 值時使用

variable environment:變量環(huán)境,當(dāng)聲明變量時使用

code evaluation state:用于恢復(fù)代碼執(zhí)行位置

Function:執(zhí)行的任務(wù)是函數(shù)時使用,表示正在被執(zhí)行的函數(shù)

ScriptOrModule:執(zhí)行的任務(wù)是腳本或者模塊時使用,表示正在被執(zhí)行的代碼

Realm:使用的基礎(chǔ)庫和內(nèi)置對象實例

Generator:僅生成器上下文有這個屬性,表示當(dāng)前生成器

3.4、函數(shù)執(zhí)行過程所需信息
var b = {}
let c = 1
this.a = 2;

正確執(zhí)行上面代碼需知道的信息:

1、varb 聲明到哪里

2、b 表示哪個變量

3、b 的原型是哪個對象

4、letc 聲明到哪里

5、this 指向哪個對象

而這些信息就是執(zhí)行上下文給出來的,下面用 var 聲明與賦值,letrealm分析執(zhí)行上下文提供的信息。

3.5、var 申明與賦值

1、立即執(zhí)行的函數(shù)表達(dá)式(IIFE),通過創(chuàng)建一個函數(shù),并且立即執(zhí)行,來構(gòu)造一個新的域,從而控制 var 的范圍。

var b = 1

2、加括號讓函數(shù)變成函數(shù)表達(dá)式

(function(){
    var a;
    //code
}());


(function(){
    var a;
    //code
})();

注意:括號有個缺點,那就是如果上一行代碼不寫分號,括號會被解釋為上一行代碼最末的函數(shù)調(diào)用。

一些不加分號的代碼風(fēng)格規(guī)范,會要求在括號前面加上分號。

;(function(){
    var a;
    //code
}())


;(function(){
    var a;
    //code
})()

winter 推薦用 void 關(guān)鍵字,語義上 void 運算表示忽略后面表達(dá)式的值,變成 undefined

void function(){
    var a;
    //code
}();

特別注意var 的特性會導(dǎo)致聲明的變量和被賦值的變量是兩個 bJavaScript 中有特例,那就是使用 with 的時候,如代碼塊二,我們先講一下代碼一

with 語句的原本用意是為逐級的對象訪問提供命名空間式的速寫方式. 也就是在指定的代碼區(qū)域, 直接通過節(jié)點名稱調(diào)用對象。
// 代碼塊一
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// 比如要改對應(yīng)的值,一般的寫法是重復(fù)寫了3次obj
obj.a = 5;
obj.b = 6;
obj.c = 7;

console.log(obj) // {a: 5, b: 6, c: 7}

// 用 with 快捷方式

with (obj) {
    a = 5;
    b = 6;
    c = 7;
}

console.log(obj) // {a: 5, b: 6, c: 7}

// 接下來看一下 with 導(dǎo)致的數(shù)據(jù)泄露
function kaimo(obj) {
    with (obj) {
        a = 1;
    }
}

var k1 = {
    a: 2
};

var k2 = {
    b: 3
}

kaimo(k1);
console.log(k1.a); // 1

kaimo(k2);
console.log(k2.a); // undefined

console.log(a); // 1 (a被泄漏到全局作用域上)

上述代碼分析:

1、創(chuàng)建了 k1 、k2 兩個對象。其中一個有 a 屬性,另外一個沒有。

2、kaimo(obj) 函數(shù)接受一個 obj 的形參,該參數(shù)是一個對象引用,并執(zhí)行了 with(obj) {...}

3、在 with 塊內(nèi)部,將 2 賦值給了 a

4、將 k1 傳遞進(jìn)去,a = 2 賦值操作找到了 k1.a 并將 2 賦值給它。

5、當(dāng) k2 傳遞進(jìn)去,k2 并沒有 a 的屬性,因此不會創(chuàng)建這個屬性,k2.a 保持 undefined

問題:為什么對 k2 的操作會導(dǎo)致數(shù)據(jù)的泄漏呢?

首先稍微講一下:JavaScript中的 LHSRHS 查詢

LHSLeft-hand Side)引用和 RHSRight-hand Side)引用。通常是指等號(賦值運算)的左右邊的引用。
console.log(gg)

比如上面這個打印,先查找并取得 gg 的值,然后將它打印出來 gg 的引用是一個 RHS 引用,沒有賦予操作

gg = 666;

上面是對 gg 的引用是一個 LHS 引用,為賦值操作找到目標(biāo)

綜上

1、當(dāng)傳遞 k2with 時,with 所聲明的作用域是 k2, 從這個作用域開始對 a 進(jìn)行 LHS 查詢。

2、k2 的作用域、kaimo(…) 的作用域和全局作用域中都沒有找到標(biāo)識符 a,因此在非嚴(yán)格模式下,會自動在全局作用域創(chuàng)建一個全局變量),在嚴(yán)格模式下,會拋出 ReferenceError 異常。

// 代碼塊二
var b;
void function(){
    var env = {b:1};
    b = 2;
    console.log("In function b:", b);
    with(env) {
        var b = 3;
        console.log("In with b:", b);
    }
}();
console.log("Global b:", b);

// 輸出結(jié)果如下:
// In function b: 2
// In with b: 3
// Global b: undefined
3.6、let
letES6 開始引入的新的變量聲明模式。

winter 簡單統(tǒng)計了下,以下語句會產(chǎn)生 let 使用的作用域:

for、 if、 switch、 try/catch/finally。
3.7、Realm
在最新的標(biāo)準(zhǔn)(9.0)中,JavaScript 引入了一個新概念 Realm。有道詞典上的意思是:"領(lǐng)域,范圍;王國"。Realm 中包含一組完整的內(nèi)置對象,而且是復(fù)制關(guān)系。
var iframe = document.createElement("iframe")
document.documentElement.appendChild(iframe)
iframe.src="javascript:var b = {};"

var b1 = iframe.contentWindow.b;
var b2 = {};

console.log(b1, b2);

// {} {}

console.log(typeof b1, typeof b2);

// 谷歌輸出: object object   火狐輸出:undefined object

console.log(b1 instanceof Object, b2 instanceof Object);

//false true

上面代碼可以看到,在瀏覽器環(huán)境中獲取來自兩個 Realm 的對象,由于 b1、 b2 由同樣的代碼 {} 在不同的 Realm 中執(zhí)行,所以表現(xiàn)出了不同的行為。

個人總結(jié)

總的來說,這一篇一臉懵逼(_(:3」∠)_),要去看看《你不知道的JavaScript》才行了。。。

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/114659.html

相關(guān)文章

  • 重學(xué)前端學(xué)習(xí)筆記十八)--JavaScript閉包執(zhí)行下文

    摘要:申明與賦值立即執(zhí)行的函數(shù)表達(dá)式,通過創(chuàng)建一個函數(shù),并且立即執(zhí)行,來構(gòu)造一個新的域,從而控制的范圍。函數(shù)接受一個的形參,該參數(shù)是一個對象引用,并執(zhí)行了。在最新的標(biāo)準(zhǔn)中,引入了一個新概念。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些要點筆記以及感悟,完整的可以加入winter的專欄...

    silencezwm 評論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記十八)--JavaScript閉包執(zhí)行下文

    摘要:申明與賦值立即執(zhí)行的函數(shù)表達(dá)式,通過創(chuàng)建一個函數(shù),并且立即執(zhí)行,來構(gòu)造一個新的域,從而控制的范圍。函數(shù)接受一個的形參,該參數(shù)是一個對象引用,并執(zhí)行了。在最新的標(biāo)準(zhǔn)中,引入了一個新概念。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些要點筆記以及感悟,完整的可以加入winter的專欄...

    liaorio 評論0 收藏0
  • 重學(xué)前端學(xué)習(xí)筆記(二十八)--通過四則運算解釋器快速理解編譯原理

    摘要:實現(xiàn)狀態(tài)機可能產(chǎn)生四種輸入元素,其中只有兩種,狀態(tài)機的第一個狀態(tài)就是根據(jù)第一個輸入字符來判斷進(jìn)入了哪種狀態(tài)用函數(shù)表示狀態(tài),用表示狀態(tài)的遷移關(guān)系,用值表示下一個狀態(tài)。運行狀態(tài)機輸出結(jié)果四語法分析語法分析根據(jù)每一個產(chǎn)生式來寫一個函數(shù)。 筆記說明 重學(xué)前端是程劭非(winter)【前手機淘寶前端負(fù)責(zé)人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學(xué)習(xí)過程的一些要點...

    Crazy_Coder 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<