你知道JavaScript中的每條語句、甚至運算式都有一個結果值嗎?
當你在瀏覽器中測試代碼時,經常會在控制台的輸出結果的最後面多出一條,大部分為undefined,這個undefined就是一個結果值。
ES7的do運算式
先從ES7的一個提案說起吧:do運算式do{...}(注意:不是do{...}while();中的do)
var a,b,c = 3;a = do { if (true) { b = c*3; }};a; //9 目前的瀏覽器暫不支援
運算式do{...}的作用就是返回它後面的語句塊的結果值,功能其實和return類似,只不過return需要通過函數來封裝後調用。
不過目前來說,我們還無法使用上面的功能,目前的規範是不允許我們獲得語句的結果值並將其賦值給一個變數的(除了使用eval(),如var a = eval('if (true) {b = c*3;}'),a的值被賦值為eval()內的語句的結果值,不建議使用eval())。
ES5規範關於結果值的規定
現在你應該大概理解了什麼是結果值了,本人翻看了ES5規範,發現JavaScript中,語句塊、語句、甚至運算式都會隱式地返回一個結果值,總結如下:
結果值是語句、運算式經過邏輯運算後的值,若無邏輯(按順序執行)則為最後一條子語句、運算式的結果值(語句可以包含子語句),簡單地說它就是一個語句、運算式的“隱式的傳回值”,JavaScript會計算每一條語句、運算式並返回一個結果值,而對於語句塊的結果值,它是最後一條最外層語句的結果值(非嵌套的子語句)。
部分瀏覽器會在控制台輸出一段代碼的最後一條語句或語句塊的結果值(本文所有代碼均使用Firefox測試,不同瀏覽器有差別)
結果值可以為任何錶達式的值,也可以為空白(;、break;、continue;),為空白時結果值為undefined。當結果值為空白時,瀏覽器會忽略該語句,而列印出上一條同級的非空的語句,若僅有自身一條同級語句則列印出undefined。
特例:var變數聲明語句、函式宣告語句的結果值為undefined。
1、變數聲明語句演算法的傳回值實際為表示該變數名稱的字串,但是這個值被變數語句演算法屏蔽掉了(for...in迴圈除外),最後返回結果為undefined
2、而對於函式宣告語句,它的結果值本人按規範解讀為該函數對象,但瀏覽器顯示為undefined,具體什麼原因,本人還不理解(可能是因為函數只是定義,未被實際執行的原因);
3、函數執行語句的結果值為:
3.1 若有throw語句,則為throw語句的結果值
3.1 若有return語句,則為return語句的結果值
3.2 若無throw、return語句則為undefined
例子:
var a,b,c = 3;if (true) {b = c*3;} //按順序執行到最後一條語句,輸出9; //undefined 單獨的空語句var d = 5; //undefined 所有的var聲明語句的結果值均為undefinedfunction foo(a){ a = a+2; return a;}//undefined 函式宣告語句的最終結果值也為undefinedfoo(1); //3 函數執行語句的結果值為函數throw、return語句的結果值,若無throw、return語句,則為undefinedif(true){a=1;}else{b=2;} //1 按邏輯計算結果執行a=1;語句{ var a = 1,b = 2; if(true){a;}else{b;} //輸出1,最後一條空語句會被忽略 ;}var a = 5;switch(a){ case 1: a+1; break; case 5: a+5; break; case 3: a+3; break;}//10 空的break;語句會被忽略var a = 5;switch(a){ case 1: a+1; break; case 5: break; //執行這裡,它這裡無同級語句 case 3: a+3; break;}//undefined
下面來具體看看錶達式的結果值有什麼用:
大部分運算式只有結果值,沒有副作用,如:var a = 2; var b = a + 3;,這裡的運算式a+3的結果值為5,被賦值給了b。
而有副作用的運算式,如:
function foo(){ a++;}var a=0;foo(); //結果值為undefined,副作用是改變了a的值
又如:
var a = 0; var b = a++;a; //1b; //0var c = a++; //結果值為undefined 副作用是c被賦值了,a變成了2 var d = a++, a; //結果值為undefined,副作用是d被賦值為2,a變成了3,實際執行的是var d = a++;var d = (a++,a);//結果值為undefined,副作用是d被賦值為3,a變成了3,實際執行的是var d = ++a;function foo(){ var e = f = 1; //運算式f=1的結果值為1,1又被賦值給e}foo();f; //1 建立了全域變數fe; //ReferenceError
指派陳述式的副作用是將'='右邊的運算式的結果值賦值給了左邊的變數,最終整個指派陳述式的結果值為變數的值,為此我們可以這樣:
function foo(a){ var b; if(a&&(b = a*10;)<50){ ... }}
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。