首頁  >  文章  >  web前端  >  解析Javascript的作用域與賦值操作

解析Javascript的作用域與賦值操作

怪我咯
怪我咯原創
2017-04-05 14:59:45941瀏覽

作用域作為一個最基礎的功能存在於各種程式語言中,它使得我們的程式設計更加靈活有趣。其基礎功能就是儲存變數中的值,然後可以對值進行存取和修改。

可能我們都知道作用域的一些概念,以及其一些擴展的一些內容閉包等,但是相對於這些可能我們去了解這些變數到底是存到了哪裡,而我們的程式是如何存取他們的會更加有趣。

var a = 1;

首先我們要了解到在我們進行宣告變數並進行賦值的時候到底誰參與了我們的整個流程。

1,引擎:它參與了整個JS程式的編譯和執行。

2,編譯器:它負責了語法分析和程式碼的產生。

3,作用域:它負責手機並維護所有的標識符也就(變數)組成的一系列查詢,並對此實施了一套十分嚴格的規則,確定目前執行的程式碼對這些標識符的存取權限。

當引擎看到var a =1;的時候它和我們所想的是不一樣的,我們想這是一個聲明,他所認為的其實是這裡有倆完全不同的聲明,一個由編譯器在編譯的時候處理,另一個則由引擎在執行時間處理。那我們來看看他們到底是怎麼工作的。

編譯器會先講var a = 1;這段程式分解成詞法單元,然後將詞法單元解析成一個樹狀結構,但是當編譯器開始進行程式碼產生的時候,他對這段程序的處理方式會有所不同。

在我們理解的範圍內,編譯器是這樣工作的:為一個變數分配內存,將其命名為a,然後講值1保存進這個變量,但事實是不同的。

1,遇到 var a 的時候,編譯器會先詢問作用域是否已經有一個該名稱的變數存在於同一個作用域的集合中。如果是,編譯器就會忽略該宣告並繼續進行編譯,不然的話他會要求作用域在目前作用域的集合中宣告一個變數命名為a。

2,然後編譯器開始為引擎產生執行所需的程式碼,這些程式碼會被用來處理 a = 1 這個賦值的運算。然後引擎運行,它會先詢問作用域,當前作用域集合中是否存在了一個叫a的變量,如果是引擎就會使用這個變量,如果否,引擎會繼續在當前作用域的上級作用域查找該變數。最後只要找到了a,引擎就會把1賦值給它,如果沒有找到,引擎就會拋出一個異常。

所以說:在新變數的賦值中存在兩個操作,第一個是編譯器宣告變量,第二個是引擎在作用域中尋找該變量,並對其賦值。

下面看一段簡單的程式碼

function demo(a){
        console.log(a)          
}
demo(2);

在繼續說之前,我們先看看LHS和RHS,顧名思義,一個左一個右。這是引擎對變數所用的兩個查詢,L和R代表的是一個賦值的左側和右側(大部分情況下),也就是說當變數出現在賦值的左側時進行LHS查詢,出現在右側時進行RHS查詢。但更確切的說法其實是RHS查詢只是簡單的找出某個變數的值,而LHS查詢則是找到變數的容器本身,以便對其進行賦值操作。那麼根據這個說法,我們可以發現RHS其實代表的應該是「非左側」。我們來看一個簡單程式碼。

var a = 1; console.log(a);

在上面的代码中,var a =1;对a的引用是一个LHS引用,而console.log(a)的a其实就是一个RHS引用。再看一个例子:

function demo(a){
        console.log(a);   
}
demo(1);

上面的代码中其实包含了RHS和LHS引用。我们理解下demo(1);的意思,它其实意味着RHS引用demo这个值,(...)意味着它需要被执行,而在执行的过程中,有一个隐式的LRS引用 a = 1; 这个查询发生在参数传递的过程中。其中的console.log(a)也是个RHS引用。

同时我们需要知道,不成功的RHS会导致抛出一个异常,而不成功的LHS引用会导致自动隐式的创建一个全局变量(非严格模式),或者抛出异常(严格模式)。

作用域的嵌套

当一个块或者函数嵌套在另一个块或者函数内时,就发生了作用域的嵌套。因此,当在当前作用域中无法找到该变量时,引擎就会在外层嵌套的作用域中继续查找(若一直没有找到会到达全局作用域),直到找到该变量。

解析Javascript的作用域與賦值操作

上图一层一层往外形成的结构就是我们常说的作用域链,最内层代表当前执行环境的作用域,最外层代表全局作用域。LHS和RHS都会在当前作用域进行查找,如果没有找到,就会向外,以此类推,如果到达全局作用域都没有找到,那无论如何这个查找过程都会停止。


以上是解析Javascript的作用域與賦值操作的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn