標籤:code 方法 erro span 引用 變數 log 查詢 作用
打算把《你不知道的JavaScript》中的知識點整理下,寫點自己的心得,同時也敦促自己看書。
先做個整體的介紹,最後會再給個綜合的例子。
RHS 查詢與簡單地尋找某個變數的值別無二致,而LHS 查詢則是試圖找到變數的容器本身,從而可以對其賦值。
LHS查詢
LHS查詢指的是找到變數的容器本身,從而可以對其進行賦值。也就是找到賦值操作的目標。
LHS查詢的時候會沿著範圍鏈進行查詢,找到的話就會將值賦值給這個變數,如果到達範圍頂端仍然找不到,就會在範圍鏈頂端建立這個變數。
舉個例子
var a=2;
var a=2;相當於var a; a=2;
這裡的a就是一個LHS引用,我們只是想要為2找到一個賦值的目標,而不會去關心這個目標(這裡為a)的值是多少什麼的。
因為var a;也就是已經把a添加到當前範圍了,所以LHS查詢a的時候,找到了a,即找到了賦值操作的目標。
如果沒有var a;那麼LHS查詢a的時候,就會找不到a,就會在範圍中建立這個變數a。
RHS查詢
RHS查詢就是普通的查詢變數的值,即擷取變數的值。
RHS查詢的時候會沿著範圍鏈進行查詢,找到的話就會取得這個值並返回,如果到達範圍頂端仍然找不到,就會拋出錯誤(比如TypeError、ReferenceError)。
舉個例子
console.log(a);
這裡的a就是一個RHS引用,因為console.log需要擷取到a的值才能輸出a的值。
當然這裡的console.log也是一個RHS引用,這裡對console 對象進行RHS 查詢,並且檢查得到的值中是否有一個叫作log 的方法。
例子中的a因為沒有聲明過,所以會拋出錯誤。
綜合例子
(function test() { a=2;});console.log(a);
例子中的test函數因為沒有執行,所以a=2;也就不會執行,也就不會進行LHS查詢,自然就沒有變數a啦。
而console.log(a)中對a進行RHS查詢時,沿著範圍鏈尋找,找不到a,所以會拋出錯誤(ReferenceError)。
不過如果立即執行的話就不會拋出錯誤。
(function test() { a=2;})();console.log(a);
在這裡括弧的作用是立即執行函數,因此指派陳述式a=2就會執行,所以會對a沿著範圍鏈進行LHS查詢,
LHS查詢找不到a,便在範圍鏈頂端(全域範圍)建立變數a.
故console.log(a)中對a進行RHS查詢時,沿著範圍鏈尋找就可以在全域範圍中找到a了,也就可以取得a的值了。
當然上面的IIFE(立即執行函數)也可以寫成另一種形勢,執行結果一樣。
(function test() { a=2;}());console.log(a);
理解LHS和RHS查詢對於理解範圍至關重要呀,並且可以協助我們解決很多bug。
你不知道的JavaScript(1)LHS查詢和RHS查詢