顧名思義档插,字面意思:
- LHS:Left Handle Side;
- RHS:Right Handle Side;
考慮如下代碼:
var a = 1; // LHS:將值1,賦值給變量a
var b = a; // RHS:查詢變量a是否聲明非区,然后獲取a的值,再LHS:賦值給變量b
一目了然盹廷,LHS和RHS的作用征绸,因此,LHS和RHS不應(yīng)該只從字面上理解它俄占,而是應(yīng)該換種方式來理解:
- LHS:賦值操作的目標(biāo)管怠;
- RHS:賦值操作的源頭;
測驗(yàn)題:
// 考查有多少次LHS和RHS操作
function foo(a) {
var b = a;
return a + b;
}
var c = foo(2);
//////////////////////分析如下//////////////////////
1. 首次執(zhí)行foo(..)函數(shù)缸榄,所以需要RHS查詢是否已有foo函數(shù)聲明渤弛;
2. 將數(shù)值2傳遞給foo函數(shù),這里有個(gè)LHS隱式操作:a = 2;
3. var b = a; 先RHS查詢變量a甚带,獲取a的值她肯,然后LHS賦值給變量b;
4. return a + b鹰贵;就是兩次RHS晴氨,分別是變量a和變量b;
5. var c = ...;將foo函數(shù)的結(jié)果LHS賦值給變量c碉输;
故LHS和RHS的操作次數(shù):
LHS => 3次
1. 隱式賦值(形參a = ...)瑞筐;
2. var b = ...;
3. var c = ...腊瑟;
RHS => 4次
1. foo(...)聚假;
2. ... = a;
3. a + ...闰非;
4. ... + b膘格;
對(duì)于LHS和RHS,還有一點(diǎn)需要說明(非嚴(yán)格模式):
當(dāng)LHS和RHS在查詢變量時(shí)(從當(dāng)前作用域财松,一級(jí)級(jí)往上查找瘪贱,直到全局作用域?yàn)橹梗┥纯兀匀徽也坏剑藭r(shí)菜秦,LHS與RHS的表現(xiàn)行為不一致甜害。
// 如下代碼
function foo(a) {
console.log(a);
b = a; // code 1
a = c; // code 2
}
foo(2);
var test = 1;
test(); // code 3
code 1 =>
變量b并沒有在任何地方聲明,且是LHS操作(將變量a賦值給變量b)球昨,LHS會(huì)如下操作:
- 查詢當(dāng)前作用域尔店,也就是foo函數(shù);
- 然后查詢?nèi)肿饔糜颍?/li>
- 停止主慰;
最終仍舊查詢不到變量b的聲明嚣州,此時(shí),LHS會(huì)在全局對(duì)象(window)中創(chuàng)建一個(gè)變量b共螺,然后將變量a的值賦值給變量b(此時(shí)该肴,變量b是全局變量);
code 2 =>
同樣藐不,變量c未在任何地方聲明也初使化匀哄,且是RHS操作(查詢變量c的值并賦值給變量a),RHS會(huì)如下操作:
- 查詢當(dāng)前作用域雏蛮,也就是foo函數(shù)涎嚼;
- 然后查詢?nèi)肿饔糜颍?/li>
- 停止;
最終仍舊查詢不到變量c的聲明底扳,此時(shí)铸抑,RHS會(huì)拋出一個(gè)異常:ReferenceError!
code 3 =>
RHS操作衷模,查詢到test有聲明鹊汛,且在全局作用域下,但是阱冶,test是一個(gè)變量刁憋,而不是函數(shù),因此木蹬,RHS會(huì)拋出一個(gè)異常:TypeError至耻!
以下對(duì)兩種異常的解釋:
1. TypeError:
試圖對(duì)一個(gè)非函數(shù)類型的值進(jìn)行函數(shù)調(diào)用,或著引用 null 或 undefined 類型的值中的
屬性镊叁,那么引擎會(huì)拋出一種類型的異常尘颓,叫作 TypeError。
2. ReferenceError:
ReferenceError 同作用域判別失敗相關(guān)晦譬,而 TypeError 則代表作用域判別成功了疤苹,
但是對(duì)結(jié)果的操作是非法或不合理的。