成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

You-Dont-Know-JS - 作用域

pingan8787 / 2262人閱讀

摘要:編譯器對賦值的操作當(dāng)編譯器遇到它會詢問域是否存在變量,如果存在編譯器忽略這個(gè)聲明,如果不存在編譯器要求域聲明一個(gè)新變量給自己。兩種引用引用和引用,對于編譯器來說,指變量用于賦值,是指變量用于取值。里面的也是引用,因?yàn)樗糜讷@取的值。

You-Dont-Know-JS是github上一個(gè)擁有9000多枚星星的JS教學(xué)文檔,評價(jià)很高,為了避免和其他翻譯文一樣,容易陷入不宜讀的混亂,也試圖避免原文中過多數(shù)的術(shù)語導(dǎo)致我露怯,我只提取提取我理解的一些點(diǎn),通俗的講出來。今天先從第一章作用域開始吧:

原文
我的翻譯folk,希望有識之士能跟我共同完成

JS的編譯

js和傳統(tǒng)語言一樣,也需要編譯執(zhí)行,編譯的過程通常分三步:

標(biāo)記+詞法分析 Tokenizing/Lexing:: 把程序語言切成一段一段的片段,稱之為tokens。比如,程序中的 var a = 2;,會被切成如下tokens:var, a, =, 2, ;。

解析 Parsing: 把token流轉(zhuǎn)換成樹,是嵌套元素形式,符合語法結(jié)構(gòu)和規(guī)則,這個(gè)樹被稱之為"AST" (Abstract Syntax Tree).
var a = 2;的樹,開始于頂層節(jié)點(diǎn) VariableDeclaration, 包含子節(jié)點(diǎn) Identifier (值 a), 另外一個(gè)子節(jié)點(diǎn) AssignmentExpression 包含另外子節(jié)點(diǎn) NumericLiteral (值 2).

代碼生成 Code-Generation: 這個(gè)過程是把AST轉(zhuǎn)換成可執(zhí)行代碼, 這部分各程序語言和個(gè)平臺之間會有極大的不同。 所以,刨除細(xì)節(jié),var a = 2;會被轉(zhuǎn)換成機(jī)器語言,在內(nèi)存中創(chuàng)建一個(gè)變量 a,而后把值儲存其中。

編譯器對賦值的操作

當(dāng)編譯器遇到var a,它會詢問域是否存在變量a,如果存在編譯器忽略這個(gè)聲明,如果不存在編譯器要求域聲明一個(gè)新變量a給自己。

編譯器而后為引擎產(chǎn)生可執(zhí)行代碼,處理a = 2, 引擎首先詢問域是否有這個(gè)變量,如果沒有執(zhí)行其他操作。

兩種引用

LHS(Left-hand Side)引用和 RHS(Right-hand Side)引用,對于編譯器來說,LHS指變量用于賦值,RHS是指變量用于取值。

function foo(a) {
    console.log( a ); // 2
}

foo( 2 );

這里,foo(), 引用(變量)foo是RHS引用,因?yàn)樗怯糜谌≈档牟僮鳎▽⒑瘮?shù)foo的值取出來),參數(shù)a被隱含賦值2,a = 2這里的引用a是LHS引用,因?yàn)樗糜谫x值。console.log(a)里面的a也是LHS引用,因?yàn)樗糜讷@取a的值。

這里說明的是, 代碼里的變量, 對于編譯器來說有兩種類型,用于獲取它值的是一種,本身是用于被賦值的是另外一種。

嵌套域 (Nested Scope)

嵌套域很好理解,如下代碼

function foo(a) {
    console.log( a + b );
}

var b = 2;

foo( 2 ); // 4

foo函數(shù)域中沒有變量b,當(dāng)引用b被調(diào)用的時(shí)候,程序會逐級往上查找,直到找到變量b,最頂層為全局變量 (global scope),如下圖所示:

錯誤

但是各位有沒有想過一個(gè)問題,被賦值的引用(LHS)如果本域內(nèi)不存在會產(chǎn)生什么情況?當(dāng)然,大多數(shù)人都經(jīng)歷過ReferenceError,引用錯誤。

當(dāng)LHS引用(賦值引用)在域中找不到的時(shí)候,js引擎會直接拋出錯誤,而RHS引用(調(diào)用引用)如果在域中找不到的時(shí)候,js引擎會向上一級域中查找,如果依然沒有,會直接在全局域中為你自動創(chuàng)建一個(gè)(非嚴(yán)格模式下, 嚴(yán)格模式下也會報(bào)ReferenceError錯誤)。

考慮從如下代碼:

function foo(a) {
    console.log( a + b );
}

foo( 2 );

這里的變量b因?yàn)樵诤瘮?shù)域中未定義,所以會報(bào)錯

function foo(a) {
    b = a;
}

foo( 2 );

這里的變量b也未定義,但是由于是復(fù)制操作,系統(tǒng)會為你在外層全局域里自動創(chuàng)建一個(gè)。

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91466.html

相關(guān)文章

  • You-Dont-Know-JS - 詞法作用

    摘要:原文原文原文詞法作用域作用域有兩種常見的模型,一種叫做詞法作用域,一種叫做動態(tài)作用域。其中詞法作用域更常見,被大多數(shù)語言采用,包括。值得注意的是,一個(gè)函數(shù)作用域只有可能存在于一個(gè)父級作用域中,不會同時(shí)存在兩個(gè)父級作用域。 原文: 原文1 | 原文2 Lexical Scope - 詞法作用域 作用域有兩種常見的模型,一種叫做 詞法作用域 Lexical Scope,一種叫做...

    bang590 評論0 收藏0
  • 閉包,又見閉包。。。。?

    摘要:完美的閉包,對,閉包就這么簡單。這僅僅是閉包的一部分,閉包利用函數(shù)作用域達(dá)到了訪問外層變量的目的。此時(shí)一個(gè)完整的閉包實(shí)現(xiàn)了,的垃圾回收機(jī)制由于閉包的存在無法銷毀變量。 1.閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。 上面這段話來自 javascript 高級程序設(shè)計(jì) 第三版 P178 。作者說閉包是一個(gè)函數(shù),它有訪問另一個(gè)函數(shù)作用域中的變量的能力。 2.函數(shù)訪問它被創(chuàng)建時(shí)所處的...

    keelii 評論0 收藏0
  • 前端_JavaScript

    摘要:為此決定自研一個(gè)富文本編輯器。例如當(dāng)要轉(zhuǎn)化的對象有環(huán)存在時(shí)子節(jié)點(diǎn)屬性賦值了父節(jié)點(diǎn)的引用,為了關(guān)于函數(shù)式編程的思考作者李英杰,美團(tuán)金融前端團(tuán)隊(duì)成員。只有正確使用作用域,才能使用優(yōu)秀的設(shè)計(jì)模式,幫助你規(guī)避副作用。 JavaScript 專題之惰性函數(shù) JavaScript 專題系列第十五篇,講解惰性函數(shù) 需求 我們現(xiàn)在需要寫一個(gè) foo 函數(shù),這個(gè)函數(shù)返回首次調(diào)用時(shí)的 Date 對象,注意...

    Benedict Evans 評論0 收藏0
  • js中的this學(xué)習(xí)

    摘要:考慮這個(gè)問題還需要了解一個(gè)概念調(diào)用棧到達(dá)當(dāng)前執(zhí)行位置而被調(diào)用的所有方法的堆棧。之后只要調(diào)用函數(shù),就會調(diào)用函數(shù),綁定的值始終不變。就是中新增的函數(shù)箭頭函數(shù)。 在之前的對象原型的文章中,我們講到了在函數(shù)前面加new然后進(jìn)行調(diào)用之后發(fā)生的4件事情,當(dāng)時(shí)只把跟原型有關(guān)的東西介紹了一下?,F(xiàn)在我們來學(xué)習(xí)一下其他的內(nèi)容。 首先先來回顧一下會有哪四件事情發(fā)生吧: 一個(gè)全新的對象被創(chuàng)建 這個(gè)新的對象會...

    roadtogeek 評論0 收藏0
  • 【理解】一道 JS 面試題

    摘要:最近在一個(gè)前端學(xué)習(xí)群里,有人拋出了這么一道面試題。以下表示形式的是函數(shù)表達(dá)式,有多種形式。函數(shù)聲明式的函數(shù)名是可修改的。重新聲明變量通過上面的分析解釋,希望你可以掌握這道面試題,舉一反三。原文鏈接理解一道面試題 最近在一個(gè)前端學(xué)習(xí)群里,有人拋出了這么一道 JS 面試題。 var foo = 1; (function foo(){ foo = 100; console.l...

    binaryTree 評論0 收藏0

發(fā)表評論

0條評論

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