JavaScript中關(guān)于作用域的詳細介紹-創(chuàng)新互聯(lián)

這篇文章將為大家詳細講解有關(guān)JavaScript中關(guān)于作用域的詳細介紹,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

創(chuàng)新互聯(lián)基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)電信機房托管報價,主機托管價格性價比高,為金融證券行業(yè)服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨享,G口帶寬及機柜租用的專業(yè)成都idc公司。

幾乎所有的編程語言都有作用域的概念,那作用域到底指的是什么呢?作用域就是編程語言在定義變量時,變量如何存儲、變量如何訪問的一套規(guī)則,不同的編程語言的規(guī)則大同小異,接下來就來看看這套規(guī)則是怎么設(shè)定的

編譯原理

在傳統(tǒng)編譯語言中,在代碼執(zhí)行之前都會有一個編譯過程:

  • 分詞/詞法分析:將代碼語句分解成有意義的代碼塊,又叫詞法單元。
  • 解析/語法分析:將詞法單元轉(zhuǎn)換一個逐級嵌套的具有語法規(guī)則的樹狀結(jié)構(gòu),又叫抽象語法樹(AST)
  • 代碼生成:解析AST并轉(zhuǎn)化成機器指令

和傳統(tǒng)編譯語言不太一樣,js的編譯和執(zhí)行并不是分開執(zhí)行,大多數(shù)情況都是編譯過程結(jié)束就會立刻執(zhí)行,為了在短時間的編譯過程內(nèi)達到較優(yōu)性能,js引擎較一般編譯器更復(fù)雜,現(xiàn)在就讓來看js的編譯過程,簡單的以編譯var a = 2為例:

  • 遇到var a,編譯器會詢問作用域是否已經(jīng)有一個該名稱的變量存在于同一個作用域的集合中。如果是,編譯器會忽略該聲明,繼續(xù)進行編譯;否則它會要求作用域在當前作用域的集合中聲明一個新的變量a
  • 接下來編譯器會為引擎生成運行時所需的代碼,這些代碼被用來處理a=2這個賦值操作。引擎運行時會首先詢問作用域,在當前的作用域集合中是否存在一個叫做a的變量。如果否,引擎就會使用這個變量;如果引擎最終找到了a,就會將2賦值給它。否則引擎就會拋出一個異常

詞法作用域

作用域一般有兩種工作模型,第一種是被大多數(shù)編程語言所采用的詞法作用域,另外一種叫作動態(tài)作用域,如Bash腳本采用的就是動態(tài)作用域。詞法作用域就是定義在詞法階段的作用域,詞法作用域是由你在寫代碼時將變量和塊作用域?qū)懺谀睦飦頉Q定的,由變量定義位置決定,而動態(tài)作用域則是由變量使用的位置來決定的。下面來看個例子:

function foo(a) {
  var b = a * 2;
  function bar(c) {
    console.log(a, b, c)
  }
  bar(b * 3)
}
foo(2)

首先來分析一下這里一共存在幾個作用域?

  1. 全局作用域,里面存在foo變量
  2. foo函數(shù)創(chuàng)建的作用域,里面有a,b,bar變量
  3. bar函數(shù)創(chuàng)建的作用域,里面有c變量

接下來再來分析一下變量的查找過程,引擎執(zhí)行console.log()需要查找a、b、c三個變量的引用,首先從最里面的bar()作用域開始找,引擎無法找到a,因此會再往上到foo()作用域中找,在這里找到了a,停止查找,對于b、c來說查找過程一樣。作用域查找始終從運行時最內(nèi)層開始查找,逐級向外查找,直到遇見第一個匹配的變量為止。

函數(shù)作用域

函數(shù)作用域指的是屬于這個函數(shù)的全部變量都可以在整個函數(shù)的范圍內(nèi)使用及復(fù)用,這是大家都知道的定義,但是函數(shù)作用域的存在到底有什么用呢?接下來就一起看看函數(shù)作用域的秒用。


隱藏內(nèi)部實現(xiàn)

隱藏內(nèi)部實現(xiàn)就是將變量和函數(shù)包裹在一個函數(shù)的作用域中,達到隱藏的目的,為什么要這么做呢?軟件設(shè)計中有一個非常有名的原則叫最小暴露原則,指最小限度暴露必要內(nèi)容,而將其他內(nèi)容都隱藏起來,比如模塊或?qū)ο蟮腁PI設(shè)計。用函數(shù)作用域來包裹變量和函數(shù)來達到最小暴露原則,阻止外部直接訪問,來看下面的例子:

function doSomething(a) {
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
}
  
function doSomethingElse(a) {
  return a - 1;
}
var b;
doSomething( 2 ); // 15”

在這段代碼中doSomethingElse和b應(yīng)該是doSomething內(nèi)部私有的,但是卻被暴露出來,這樣會導(dǎo)致以預(yù)期之外的形式被使用,產(chǎn)生意料之外的結(jié)果,更合理的設(shè)計應(yīng)該是將這些私有的內(nèi)容隱藏在doSomething內(nèi)部,例如:

function doSomething(a) {
  function doSomethingElse(a) {
    return a - 1;
  }
  var b;
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
}
doSomething( 2 );

這樣b和doSomethingElse都無法從doSomething外部訪問,但是這樣也會存在一些問題,首先在全局作用域中聲明了doSomething函數(shù),污染了全局作用,其次,必須通過顯示調(diào)用才能執(zhí)行,那么有沒有什么辦法既不會污染作用域也不需要調(diào)用就可以自執(zhí)行呢?答案就是函數(shù)表達式,看下面的例子:

(function doSomething(a) {
  function doSomethingElse(a) {
    return a - 1;
  }
  var b;
  b = a + doSomethingElse( a * 2 );
  console.log( b * 3 );
})(2)

首先來看(function doSomething(){})這是一個函數(shù)表達式,和函數(shù)聲明不同的是用括號包起來的,然后再(function doSomething(a){})()調(diào)用傳值,這樣既能自執(zhí)行也不會污染作用域,社區(qū)給這種用法定義了一個術(shù)語:IIFE,代表立即執(zhí)行函數(shù)表達式

塊作用域

除JavaScript外很多編程語言都支持塊作用域,盡管你可能寫過很偽塊作用域形式的代碼,最常見的就是for循環(huán):

for(var i=0; i<10; i++) {
  console.log(i)
}

寫這段代碼通常是希望變量i在循環(huán)內(nèi)部使用,但是實際上i會被綁定到外部作用域中,要確保沒有在作用域的其他地方意外使用i,就只能依靠自覺,這時候塊級作用域就顯得尤為有用,ES6改變了現(xiàn)狀,引入了新的let、const關(guān)鍵字,let關(guān)鍵字可以將變量綁定到所在的任意作用域中,也就是let為其聲明的變量隱式地創(chuàng)建了作用域:

for(let i=0; i<10; i++) {
  console.log(i)        
}
console.log(i) // ReferenceError

這時候i就只會在for循環(huán)的內(nèi)部有效

關(guān)于JavaScript中關(guān)于作用域的詳細介紹就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

新聞標題:JavaScript中關(guān)于作用域的詳細介紹-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://muchs.cn/article0/dpedio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站、響應(yīng)式網(wǎng)站、企業(yè)建站、網(wǎng)站制作服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)