1. 程式人生 > 實用技巧 >你不知道的 JavaScript 系列中( 31 ) - 讓人誤解的語句

你不知道的 JavaScript 系列中( 31 ) - 讓人誤解的語句

語句的結果值
var a = 3 * 6;
var b = a;
b;
以賦值表示式 b = a 為例,其結果值是賦給 b 的值(18),但規範定義 var 的結果值是 undefined。如果在控制檯中輸入var a = 42會得到結果值 undefined,而非 42 如果你用開發控制檯除錯過程式碼,應該會看到很多語句的返回值顯示為 undefined,只是你可能從未探究過其中的原因。 其實控制檯中顯示的就是語句的結果值
var b;
if (true) {
  b = 4 + 38;
}

在控制檯中輸入以上程式碼應該會顯示 42,即最後一個語句 / 表示式 b= 4 + 38 的結果值。 換句話說,程式碼塊的結果值就如同一個隱式的返回,即返回最後一個語句的結果值。

下面這樣的程式碼無法執行:
var a, b;
a = if (true) {
  b = 4 + 38;
};

因為語法不允許我們獲得語句的結果值並將其賦值給另一個變數(至少目前不行)



表示式的副作用
var a = 2;
var b = a + 3;
表示式 a + 3 本身沒有副作用(比如改變a的值)。它的結果值為5,通過 b = a + 3 賦值 給變數 b。
var a = 42;
var b = a++;

a++ 首先返回變數 a 的當前值 42(再將該值賦給 b),然後將 a 的值加 1:

var a = 42;
var
b = a++; a;
// 43 b; // 42

很多開發人員誤以為變數 b 和 a 的值都是 43,這是因為沒有完全理解 ++ 運算子的副作用 何時產生。

var a = 42;
a++; // 42
a; // 43
++a; // 44
a; // 44
++ 在前面時,如 ++a,它的副作用(將 a 遞增)產生在表示式返回結果值之前,而 a++ 的 副作用則產生在之後 但也不是沒有辦法,可以使用,語句系列逗號運算子(statement-series comma operator)將 多個獨立的表示式語句串聯成一個語句:
var a = 42, b;
b = ( a++, a );
a; // 43
b; // 43
a++, a中第二個表示式a在a++之後執行,結果為43,並被賦值給b。



上下文規則 {}
// 假定函式bar()已經定義
var a = {
  foo: bar()
};

{ .. }被賦值給a,因而它是一個物件常量

{
  foo: bar()
}

{ .. } 在這裡只是一個普通的程式碼塊。JavaScript 中這種情況並不多見(在其他語言中則常見得多),但語法上是完全合法的,特別是和 let(塊作用域宣告)在一起時非常有用

還有一個坑常被提到(涉及強制型別轉換,參見第 4 章):
[] + {}; // "[object Object]"
{} + []; // 0
第一行程式碼中,{} 出現在 + 運算子表示式中,因此它被當作一個值(空物件)來處理。[]會被強制型別轉換為"",而{}會被強制型別轉換為"[object Object]"。 但在第二行程式碼中,{} 被當作一個獨立的空程式碼塊(不執行任何操作)。程式碼塊結尾不需 要分號,所以這裡不存在語法上的問題。最後+ []將[]顯式強制型別轉換(參見第4章) 為0。


else if 和可選程式碼塊

很多人誤以為JavaScript中有else if,因為我們可以這樣來寫程式碼:
if (a) {
  // ..
}else if (b) {
  // ..
}else {
  // ..
}

事實上 JavaScript 沒有 else if,但 if 和 else 只包含單條語句的時候可以省略程式碼塊的 { }。下面的程式碼你一定不會陌生:

if (a) doSomething( a );
很多JavaScript程式碼檢查工具建議對單條語句也應該加上{ },如:
if (a) {
  doSomething( a );
}

else也是如此,所以我們經常用到的else if實際上是這樣的:

if (a) {
  // ..
}else {
  if (b) {
    // ..
  }else {
    // ..
  }
}

if (b) { .. } else { .. }實際上是跟在else後面的一個單獨的語句,所以帶不帶{ }都可以。換句話說,else if不符合前面介紹的編碼規範,else中是一個單獨的if語句。 else if 極為常見,能省掉一層程式碼縮排,所以很受青睞。但這只是我們自己發明的用法,切勿想當然地認為這些都屬於 JavaScript 語法的範疇。