介紹JavaScript中的運算子 (Operators) 的用法,包含邏輯運算子 (Logical Operator)、字串運算子 (String Operator) 和特殊運算子 (Special Operator)。

邏輯運算子

邏輯運算子 (Logical Operator) 在程式語言中一般用來做布林代數使用,進行複數的條件判斷,例如:

1
n >= 0 && n <= 100

包含以下運算子

範例說明
a && b邏輯 AND,a 為 true 且 b 為 true,則回傳 true
a || b邏輯 OR,a 為 true 或 b 為 true,則回傳 true
!a邏輯NOT,a 為 false,則回傳 true

然而 JavaScript 和其它語言在 &&|| 邏輯運算子的行為上有些不同之處。

邏輯 AND(&&)

JavaScript 中的 && 回傳的結果並不一定是布林值,實際上他會依據以下規則回傳運算結果:

  1. 如果運算式轉為布林值為 false,則回傳該數值。(例如 0, null, undefined, NaN 和空字串)
  2. 如果為 true,則回傳右邊運算式的數值;換句話說,當全部成立時,回傳最右邊運算式的數值。
1
2
true && null && 100 // null
true && {} && 100 // 100

而如同一般程式語言一樣,如果左方的運算式結果為false時,將不會執行右邊的運算式:

1
false && neverExec() // 右邊的函式將永遠不會觸發

邏輯 OR(||)

如同 AND 一樣,JavaScript 中的 || 回傳結果不一定是布林值,他會依據以下規則回傳運算結果:

  1. 如果運算式轉為布林值為 true,則回傳該數值。
  2. 如果為 false,則回傳右邊運算式的數值;如果全部為 false,則回傳 false。

而如同一般程式語言一樣,如果左方的運算式結果為 true 時,將不會執行右邊的運算式:

1
true || neverExec() // 右邊的函式將永遠不會觸發

除此之外,由於 OR 的特性,時常會被拿來利用作為指派預設值之用:

1
option = option || 'default';

字串運算子

字串運算子 (String Operator) 使用 + 號作為連接字串之用,由於和算術運算子的數值相加符號一樣,所以在數字和字串混合使用的時候可能需要注意,避免產生未預期的結果,可以看以下範例:

1
2
3
4
1 + '2' // 12
1 + 2 + '3' // 33
'1' + 2 + 3 // 123
'1' + (2 + 3) // 15

執行順序為由左至右,當遇到字串之後才會變成字串連接,在變成字串之前還是會使用算術相加,可使用括號先執行算術運算後在轉為字串連接。

特殊運算子

JavaScript 中包含一些其他的特殊運算子 (Special Operator),以下逐一介紹。

條件運算子

條件運算子 (Conditional Operator) 是唯一的三元運算子,語法如下:

1
expr ? true_val : false_val

使用範例如下:

1
2
3
score >= 60 ? 'pass' : 'fail'
n > 0 ? 100 / n : 0
a > b ? a : b

逗號運算子

逗號運算子 (Comma Operator) 使用逗號 (,) 隔開鎂個運算式,並回傳最右邊的運算式結果,這個運算子通常用在迴圈之中,同時對多個變數進行變量操作,例如:

1
2
3
for (var i = 0, j =0; i < 10; ++i, j += 2) {
sum += i * j;
}

陣列與物件存取運算子

我們可以透過中括號 ([]) 來存取陣列的元素,而物件的成員我們可以用點 (.) 和中括號 ([]) 來存取,例如以下範例:

1
2
3
4
5
var a = [123];
a[0] // 123
var o = { n: 456 };
o.n // 456
o['n'] // 456

其中物件也可以使用中括號代字串的方式存取成員,利用此特性可以透過程式的方式動態的存取不同的成員:

1
2
3
4
5
var o = {};
for (var i = 0; i < 5; ++i) {
o['n' + i] = i;
}
o // { n0: 0, n1: 1, n2: 2, n3: 3, n4: 4 }

in

in 運算子可以用來判斷一個物件是否包含某個屬性,並回傳布林結果,範例如下:

1
2
3
4
5
6
7
8
9
10
11
var army = { black: 'color', fault: null, illegal: undefined };
console.log('black' in army); // true
console.log('fault' in army); // true, 即使宣告 null 或 undefined 也是存在
console.log('illegal' in army); // true
console.log('truth' in army); // false

var arr = [1, 2, 'hello'];
console.log(1 in arr); // true, 實際上指的是 arr[1] 存在
console.log('1' in arr); // true, arr['1']
console.log('hello' in arr); // false, arr['hello'] 不存在
console.log(3 in arr); // false, arr[3] 不存在

注意以上陣列的用法,並不是以值有沒有在陣列之中作為判斷。

instanceof

instanceof 運算子可以用來判斷一個實例 (instance) 是否為某一種類型所建構出來,左邊必須放要被判斷的實例,右邊必須為類別建構式,以下為一個範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
function Cat() {}
Cat.prototype = new Animal();

var dog = new Dog();
console.log(dog instanceof Animal); // true
console.log(dog instanceof Dog); // true
console.log(dog instanceof Cat); // false
console.log(dog instanceof Object); // true

console.log(Dog instanceof Animal); // false

以上範例簡單的建立了一些繼承關係,透過繼承關係的範例可以容易理解運作的意涵。

typeof

typeof 運算子可以用來取得一個物件的型別,在之前的文章 JavaScript 教學 - 資料型態 (Data Type) - 上中已經有介紹過,不過值得注意的地方是,自定的類別物件使用 typeof 只會回傳"object" 的字串,如果要進一步判斷是哪一種類別,必須使用上面的 instanceof 的運算子。

new

new 運算子可以用來產生物件實例,比較特別的是,在 JavaScript 中,如果不帶參數允許省略括號,一些範例如下:

1
2
3
var date = new Date();
var obj = new Object;
var point = new Point(x, y);

delete

delete 運算子可以用來移除物件的屬性、陣列元素或變數,並回傳是否成功的布林結果,以下兩種情況的物件屬性是無法刪除的:

  1. 核心屬性,例如 window.document
  2. var 宣告的變數。

JavaScript中 的 delete 只是將該屬性或元素的參考連結移除,並不會直接將該物件作釋放記憶體的動作。delete 和將值設成 undefinednull 是不一樣的意思,delete 後該屬性將不會存在。另外在標準中的定義,如果對象不是屬性、陣列元素或變數時也是會回傳 true,以下為一些範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
console.log(delete window.document); // false

var a = 1;
console.log(window.a); // 1
console.log(delete window.a); // false
console.log(window.a); // 1

b = 2;
console.log(window.b); // 2
console.log(delete window.b); // true
console.log(window.b); // undefined

c = 3;
console.log(window.c); // 3
console.log(delete c); // true
console.log(window.c); // undefined

var arr = ['Test', 178];
arr[0] = undefined;
console.log(0 in arr); // true
console.log(delete arr[0]); // true
console.log(0 in arr); // false

console.log(delete nofound); // true
console.log(delete "you can't delete"); // true

void

void 運算子可以執行一段運算式,然後不回傳結果 (也就是回傳 undefined),實務上最常使用在超連結之中,用來執行一段 JavaScript 語法而避免頁面跳轉 (一些舊的瀏覽器需要回傳 undefined 才不會跳轉),例如:

1
<a href="javascript: void(alert('Hello'))">Click</a>

早期也用作產生 undefined 數值之用。

get / set

在一些程式語言中,支援使用屬性的方式來處理 getter / setter,而在 JavaScript 1.8.5 版本加入了這項實作,宣告與使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
var user = {
get Name() {
return this.name || 'Anonymous';
},
set Name(value) {
this.name = value.charAt(0).toUpperCase() + value.slice(1);
}
}

console.log(user.Name); // Anonymous
user.Name = 'john';
console.log(user.Name); // John

不過由於這個功能是比較新版本的瀏覽器才有支援,所以在普及之前可能還是避免使用。

let

JavaScript 1.7 中提出了 let 的操作子,不過目前似乎未被大部份瀏覽器納入支援,故暫時不做介紹。

yield

JavaScript 1.7 中提出了 yield 的操作子,不過目前似乎未被大部份瀏覽器納入支援,故暫時不做介紹。

延伸閱讀

上一篇 JavaScript 教學 - 運算子 (Operators) - 上