0%

JS核心(10)-運算子、型別與文法-陳述式與表達式

前言

陳述式(Statement)與表達式(Expression)最大的差別在:陳述式不會回傳結果

陳述式與表達式

陳述式與表達式

可以透過 MDN 文件了解 JavaScript 的陳述式 陳述式表達式 有那些

陳述式有 varletconstif...elsefor …等等
表達式經常會與運算子搭配並回傳結果

陳述式 (Statement)

基本上陳述式是不會回傳結果的,在這邊你應該會覺得很奇怪,剛才不是說表達式通常會搭配運算子並回傳結果嗎?那麼變數宣告的 var a = 1; 有回傳一個 undefined 為什麼不算是一個表達式呢?而且他也有 = 運算子,這樣子不算是表達式嗎?

相信很多人對於「變數宣告」為什麼是一個陳述式感到疑惑,陳述式最簡單的觀念來自「它只會靜靜躺在那邊等你呼叫,最大特徵在於不會回傳任何的結果,但是陳述式必定會先執行過一次」,其主要原因在於它要先確定語法作用域。

因此若在 Chrome 上的 console 輸入 var a = 1; 卻會回傳 undefined 的原因在於變數宣告時,JavaScript 會先執行過一次,因為它要替這個變數準備一個記憶體空間,並將記憶體空間與變數名稱對應,但並不會回傳結果,因此變數宣告才會回傳給你一個 undefined,而在這邊的 undefined 只是告訴你我已經替這個變數宣告準備好了記憶體空間而已。

表達式 (Expression)

表達式又稱之為運算式,也可以稱為表示式,最間單的觀念理解在於它會回傳一個值,例如當你輸入 1+1 它會在底下回傳一個 2,而這就是表達式

> 1+1
< 2

在 MDN 中有說明運算式的幾個特徵

算數: 解析出數字, 例如 3.14159. (通常使用 算術運算子)
字串: 解析出字串, 例如 “Fred” or “234”。 (通常使用 字串運算子)
邏輯: 解析出 True 或 False (通常與 邏輯運算子 相關)
主流運算式: JavaScript 基本的關鍵字及運算式
左側運算式: 左側是指定值的對象

表達式最簡單的便是觀念在於「會回傳一個結果 or 一個值」,因此當我們輸入 hi = 'Bob' 它會回傳一個 'Bob' 這就是表達式

> hi = 'Bob';
< 'Bob'

而表達式的重點觀念在於運算子,因此等號是一個表達式,它會將值賦予到 hi 並回傳結果,因此我們這邊可以回顧一下變數宣告中的 var a = '10'; 為什麼會回傳 undefined,前面有說過變數宣告會回傳 undefined 的原因在於它準備好一個空間給記憶體給變數使用,接下來讓我們看一下其他陳述式通常會發生什麼事情

if(true) {
}
//undefined

function fu() {}
//undefined

for(var i; i< 10;i++) {}
//undefined

你會發現只要是陳述式它就只會回傳 undefined

反之表達式就不同,表達式必定會回傳一個結果一個值

hi = 'Bob';
//'Bob'

1+1;
//2

w = true;
//true

d = function () {}
//f () {}

另外,我們常在開發使用的 setTimeout 以及 setInterval 也是屬於表達式

> setTimeout(function(){}, 10000); // 1000 = 1 秒
< 7

> setInterval(function(){}, 10000);
< 8

此外陳述式與表達式還有一個特徵可以辨別,也就是陳述式無法被變數儲存,因為陳述式不會回傳值的關係

a = if (true) {};
// Uncaught SyntaxError: Unexpected token 'if'

函式陳述式

接下來講另一種的陳述式與表達式,函式在宣告時其實也有分為兩種廣義的宣告方式,第一種就是所謂的函式陳述式

function fu() {

}

基本上函式陳述式在宣告時,並不會回傳結果,而是與前面相同,僅會回傳 undefined,此外上面的函式陳述式又稱之為具名函式陳述式

函式表達式

函式表達式通常會宣告一個變數並搭配等號運算子以及一個函式,而這個就是所謂的函式表達式

var fu = function() {}

而這個宣告函式的方式又稱之為匿名函式表達式,雖然你在 Chrome 中,輸入他一樣會回傳給你一個 undefined,但實際上因為這個函式沒有 name 所以會被回傳儲存在 fu 的變數內,而函式表達式最大的特徵在於他不會受到提升的影響,因此若你在函式表達式之前呼叫,它就會出現錯誤訊息

fu();  
var fu = function() {}
//Uncaught TypeError: fu is not a functionat <anonymous>:1:1

block 與物件實字

在 JavaScript 中有一個 block,也就是 {}, block 在 MDN 中也是屬於陳述式,因此可以這樣寫

{
  var hi = 'Bob';
}

但是若是改寫成物件實字則是使用「:」來區分屬性與值

{
  hi: 'Bob',
}

而這邊兩者最大差異在於物件實字是一個表達式,因此表達式我們可以儲存進變數內中

var a = {
  hi: 'Bob',
};

但若是 block 則是不行,因為他是一個陳述式

var b = {
  var hi = 'Bob';
}
// Uncaught SyntaxError: Unexpected identifier

結論
只要會回傳結果或是值,那麼就是屬於表達式,若不會那麼就是陳述式