摘要:詞法作用域定義與查找詞法作用域就是定義在詞法階段的作用域,簡(jiǎn)單來說詞法作用域是由你在寫代碼時(shí)將變量和塊作用域?qū)懺谀睦飦頉Q定的,因此大部分情況下當(dāng)詞法分析器處理代碼時(shí)會(huì)保持作用域不變此例中一共由三個(gè)逐級(jí)嵌套的作用域包含這整個(gè)全劇作用域,其中只
詞法作用域 定義與查找
詞法作用域就是定義在詞法階段的作用域,簡(jiǎn)單來說詞法作用域是由你在寫代碼時(shí)將變量和塊作用域?qū)懺谀睦飦頉Q定的,因此大部分情況下當(dāng)詞法分析器處理代碼時(shí)會(huì)保持作用域不變
function foo(a) { var b = a * 2; function bar(c) { console.log(a, b, c) } bar(b * 3) } foo(2) // 2, 4, 12
此例中一共由三個(gè)逐級(jí)嵌套的作用域:
包含這整個(gè)全劇作用域,其中只有一個(gè)標(biāo)識(shí)符:foo
包含著foo所創(chuàng)建的作用域,其中有三個(gè)標(biāo)識(shí)符:a、bar和b
包含著bar所創(chuàng)建的作用,其中只有一個(gè)標(biāo)識(shí)符:c
作用域查找過程
當(dāng)引擎執(zhí)行console.log(a, b, c)聲明時(shí),它首先會(huì)從最內(nèi)層的bar()函數(shù)作用域開始查找,在這里找到了c
因?yàn)闊o法找到a和b,因此會(huì)到再上一層的foo()作用域去查找
作用域查找會(huì)在找到第一個(gè)匹配的標(biāo)識(shí)符時(shí)停止
無論函數(shù)在哪里被調(diào)用,也無論它如何被調(diào)用,它的詞法作用域都只由函數(shù)被聲明時(shí)所處的位置決定
函數(shù)作用域指的是屬于這個(gè)函數(shù)的全部變量都可以在整個(gè)函數(shù)的范圍內(nèi)使用及復(fù)用,包括嵌套的作用域,這種設(shè)計(jì)方案非常有用。
隱藏內(nèi)部實(shí)現(xiàn)在軟件設(shè)計(jì)中,應(yīng)該最小限度地暴露必要內(nèi)容,而將其他內(nèi)容都隱藏起來,這個(gè)原則在如何在如何選擇作用域來包含變量和函數(shù)也同樣適用,例如:
var b; function one(a) { b = a + another(a) console.log(b) } function another(a) { return a*2 } one(2) // 6
在這段代碼中,給予外部函數(shù)b和another訪問權(quán)限不僅沒有必要,而且可能會(huì)被以非預(yù)期的方式使用,因此更加合理的設(shè)計(jì)會(huì)將這些內(nèi)容隱藏在one()內(nèi)部,例如:
function one(a) { function another(a) { return a*2 } var b b = a + another(a) console.log(b) } one(2) //6
這樣設(shè)計(jì)b和another()都無法從外部被訪問,功能和最終效果都沒有受影響,但是設(shè)計(jì)上將具體內(nèi)容私有畫
立即執(zhí)行行數(shù)表達(dá)式通過前面的介紹已經(jīng)知道,在任意代碼片段外部添加包裝函數(shù),可以將內(nèi)部變量和函數(shù)定義隱藏起來,外部作用域無法訪問包裝函數(shù)內(nèi)部的任何內(nèi)容。例如:
var a = 0 function ex() { var a = 1 console.log(a) // 1 } ex(); console.log(a)// 0
雖然這樣可以解決一部分問題,但是并不理想,會(huì)將ex這個(gè)變量污染全局作用域,并且需要調(diào)用才能運(yùn)行其中的代碼,javascript提供了解決問題的方案:立即執(zhí)行函數(shù)表達(dá)式(IIFE)
var a = 0; (function () { var a = 1 console.log(a) //1 })(); console.log(a) //0
此時(shí)就不會(huì)有函數(shù)名泄漏到全局作用域,并且會(huì)自動(dòng)執(zhí)行,同時(shí)外部的作用域也無法直接訪問立即執(zhí)行函數(shù)內(nèi)的變量
塊作用域事實(shí)上javascript在ES6之前并沒有塊作用域的概念,但是其他很多編程語言都支持塊作用域,ES6之前javascript循環(huán):
for (var i=0; i<3; i++) { console.log(i) //0, 1, 2 } console.log(i) //3
雖然我們的代碼看起來i只會(huì)在for循環(huán)內(nèi)部使用,但是很不幸,i會(huì)被泄漏到全局的作用域中,污染全局作用域,即使這并是我們本意,但是在ES6改變了現(xiàn)狀,引入了新的let關(guān)鍵字,提供了除var以外的另一種變量聲明方式,let可以將變量綁定到所在的任意作用域中,即為其聲明的變量隱式地劫持了所在的作用域
for (let i=0; i<3; i++) { console.log(i) //0, 1, 2 } console.log(i) // i is not defined
以上內(nèi)容是個(gè)人的一點(diǎn)總結(jié),如果有錯(cuò)誤或不嚴(yán)謹(jǐn)?shù)牡胤?,歡迎批評(píng)指正,如果喜歡,歡迎點(diǎn)贊收藏
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/91869.html
摘要:也正因?yàn)檫@個(gè)閉包的特性,閉包函數(shù)可以讓父函數(shù)的數(shù)據(jù)一直駐留在內(nèi)存中保存,從而這也是后來模塊化的基礎(chǔ)。只有閉包函數(shù),可以讓它的父函數(shù)作用域永恒,像全局作用域,一直在內(nèi)存中存在。的本質(zhì)就是如此,每個(gè)模塊文件就是一個(gè)大閉包。 為什么會(huì)有閉包 js之所以會(huì)有閉包,是因?yàn)閖s不同于其他規(guī)范的語言,js允許一個(gè)函數(shù)中再嵌套子函數(shù),正是因?yàn)檫@種允許函數(shù)嵌套,導(dǎo)致js出現(xiàn)了所謂閉包。 function...
摘要:所以的作用域是靜態(tài)作用域,也叫詞法作用域。總結(jié)是一門基于詞法作用域靜態(tài)作用域的語言,會(huì)沿著作用域鏈像氣泡一樣向外部尋找變量聲明。又是函數(shù)作用域的語言,在中,使用和關(guān)鍵字后,能讓變量處于塊作用域中,而且不存在聲明提升。 本文共 1700 字,讀完只需 7 分鐘 概述 變量,編程語言中我們用來模擬現(xiàn)實(shí)概念的工具,比方說,變量可以表示對(duì)象,數(shù)組,數(shù)字,字符。既然是工具,那么就用工具的適用范圍...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
摘要:是詞法作用域工作模式。使用可以將變量綁定在所在的任意作用域中通常是內(nèi)部,也就是說為其聲明的變量隱式的劫持了所在的塊級(jí)作用域。 作用域與閉包 如何用js創(chuàng)建10個(gè)button標(biāo)簽,點(diǎn)擊每個(gè)按鈕時(shí)打印按鈕對(duì)應(yīng)的序號(hào)? 看到上述問題,如果你能看出來這個(gè)問題實(shí)質(zhì)上是考對(duì)作用域的理解,那么恭喜你,這篇文章你可以不用看了,說明你對(duì)作用域已經(jīng)理解的很透徹了,但是如果你看不出來這是一道考作用域的題目,...
閱讀 792·2021-11-22 13:52
閱讀 1594·2021-09-27 13:36
閱讀 2912·2021-09-24 09:47
閱讀 2295·2021-09-22 15:48
閱讀 3657·2021-09-22 15:39
閱讀 1527·2019-08-30 12:43
閱讀 2980·2019-08-29 18:39
閱讀 3266·2019-08-29 12:51