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

 

6. 邏輯運算子

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

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和其它語言在&&和||邏輯運算子的行為上有些不同之處。

6.1 邏輯AND(&&)

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

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

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

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

6.2 邏輯OR(||)

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

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

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

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

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

option = option || 'default'; 

7. 字串運算子

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

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

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

8. 特殊運算子

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

8.1 條件運算子

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

expr ? true_val : false_val

使用範例如下:

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

8.2 逗號運算子

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

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

8.3 陣列與物件存取運算子

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

var a = [123];
a[0] // 123
var o = {n: 456};
o.n // 456
o['n'] // 456

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

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

8.4 in

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

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]不存在

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

8.5 instanceof

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

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

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

8.6 typeof

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

8.7 new

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

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

8.8 delete

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

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

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

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

8.9 void

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

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

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

8.10 get / set

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

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

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

8.11 let

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

8.12 yield

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

延伸閱讀

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

相关文章