Skip to main content

[JS] JavaScript 運算子(Operator)

運算式與運算子 @ MDN

[TOC]

條件判斷(conditional statement)#

  • 物件(object): 都是 true(空物件也是 true)
  • 陣列(array):陣列是一種物件,因此都會是 true(空陣列 [] 也是 true)
  • Undefined: 是 false
  • Null:是 false
  • 布林(Booleans):會根據 Boolean 值回
  • 數值(Numbers):除了 0, or NaN 會是 false 外,其他都是 true
  • 字串(String):除了空字串 '' 會是 false 之外,其他都是 true(字串中有空格也是 true)

code style#

// 單行的 if 可以不用加上 {...}
if (lemons) console.log('hello');

16.1 Use braces with all multi-line blocks @ airbnb

  • 不要在 else 中使用 return

16.3 no-else-return @ airbnb

// bad
function foo() {
if (x) {
return x;
} else {
return y;
}
}
// good
function foo() {
if (x) {
return x;
}
return y;
}
// bad
function cats() {
if (x) {
return x;
} else if (y) {
return y;
}
}
// good
function cats() {
if (x) {
return x;
}
if (y) {
return y;
}
}
  • if 當中的條件式太長的時候,可以換行並把比較運算子放在最前面(17.1 @ airbnb):
// good
if (foo === 123 && bar === 'abc') {
thing1();
}
// good
if (
(foo === 123 || bar === 'abc') &&
doesItLookGoodWhenItBecomesThatLong() &&
isThisReallyHappening()
) {
thing1();
}
// good
if (foo === 123 && bar === 'abc') {
thing1();
}

比較運算子(comparison operator)#

  • 使用 ===!==

其餘參數(rest parameter)#

其餘運算字會幫助我們把輸入函式中的參數值變成陣列的形式(多個值 => 陣列):

let avg = function (...arr) {
console.log(arr); // [1,3,5,7,9]
};
console.log(avg(1, 3, 5, 7, 9));

展開語法(spread syntax)#

展開運算子則是可以把陣列中的元素取出(陣列 => 多個值):

複製陣列(Copy an array)#

var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected

連結陣列(concatenate arrays)#

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // [ 0, 1, 2, 3, 4, 5 ]

將陣列代入函式中#

let number = [1, 2, 3, 4, 5];
console.log(Math.max(...number)); // 5
console.log(...number); // 1,2,3,4,5

複製物件(Copy Objects)#

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
// 使用 Object.assign() 會觸發 setters,而 spread syntax 不會
var clonedObj = { ...obj1 }; // Object { foo: "bar", x: 42 }
var mergedObj = { ...obj1, ...obj2 }; // Object { foo: "baz", x: 42, y: 13 }

邏輯運算子#

keywords: short circuit boolean operator#
double and &&#
// 原則:如果前者為真,則回傳後者;如果前者為假,則回傳前者,後面的都不考慮
console.log(3 === 3 && 'apple' === 'apple'); // true(因為 'apple' === 'apple')
console.log(3 === 3 && 'apple'); // 'apple',如果自己為真,則回傳後者
console.log(3 === 3 && 'apple' && 'chicken'); // 'chicken'
console.log(3 === 3 && false && 'chicken'); // 'false',如果自己為假,就會回傳它自己
使用情境#
// 使用情境:判斷前面的項目是不是都正確,如果是的話,在執行後者
callback && callback(); // 如果 callback 存在,則執行()
/**
* 如果 token.authenticate 存在則 secret = token.number
* 否則 secret = token.authenticate
**/
let secret = token.authenticate && token.number;
double or ||#
// 原則:如果前者為真,則回傳前者,後面都不考慮;如果前者為假,則回傳後者
console.log(3 === 3 || false || 'chicken'); // true(因為 3 === 3)
console.log(3 === 4 || false || 'chicken'); // 'chicken'
// 使用時機:設定預設值時
let width = window.innerHeight || 300; // 如果 window.innerHeight 不存在,則 width 為 300

switch case#

當需要在 switch 的 case 中定義變數時,casedefault 後面要加上大括號{ }

// bad
switch (foo) {
case 1:
let x = 1;
break;
case 2:
const y = 2;
break;
case 3:
function f() {
// ...
}
break;
default:
class C {}
}
// good
switch (foo) {
case 1: {
let x = 1;
break;
}
case 2: {
const y = 2;
break;
}
case 3: {
function f() {
// ...
}
break;
}
case 4:
bar();
break;
default: {
class C {}
}
}

15.5 Use braces to create blocks in case and default clauses that contain lexical declarations (e.g. let,const, function, and class). @ airbnb

位元 NOT 運算子(波浪號)#

任何 >=0 的值都會是非 0 的結果

/**
* 使用情境:用在判斷式
* 如果是 indexOf 回傳的值是 -1 表示找不到,那麼加上 ~ 之後會變 0 ,放在 if 裡面變成 false
**/
// 等同於 if(String.indexOf('e') >= 0){ ... }
if (~String.indexOf('e')) {
console.log('Find it');
}
// 用在正數無條件捨去,類似 Math.floor() 但是當裡面的數值為負數時則結果不同
console.log(~~1.45345); // 1

條件三元判斷式(ternary operator)#

Conditional (ternary) operator @ MDN

// (條件) ? 條件成立 : 條件不成立
const status = age >= 18 ? 'adult' : 'minor';

串連使用三元判斷式(conditional / ternary chains)#

由於 ternary operator 從程式的最右邊開始看(right-associative),因此若串連起來的話,等同於 if...else if ... else if ... else ... 的用法:

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
function example() {
return condition1 ? value1
: condition2 ? value2
: condition3 ? value3
: value4;
}
// Equivalent to:
function example() {
if (condition1) { return value1; }
else if (condition2) { return value2; }
else if (condition3) { return value3; }
else { return value4; }
}

例如:

const foo = (num: number): string => {
return num < 10 ? '< 10'
: num < 20 ? '< 20 '
: num < 30 ? '< 30'
: '>= 30'
}
// 等同於
const foo = (num: number): string => {
if (num < 10) {
return '< 10'
} else if (num < 20) {
return '< 20'
} else if (num < 30) {
return '< 30'
} else {
return '>= 30'
}
}
console.log(foo(5)) // '<10'

空值聯合運算子(nullish coalescing operator)#

Nullish Coalescing Operator @ MDN

可以視為 || 的強化版。當使用 nullish coalescing operator (??) 時,只有當左側的值是 nullundefined 時,才會採用右側的值,否則會使用左側的值:

// 當左側的值是 undefined 或 null 時,則回傳右側的值
undefined ?? 'foo'; // foo
null ?? 'foo'; // foo
// 除了 undefined 或 null 之外,則都會回傳左側的值
false ?? 'foo'; // false
0 ?? 'foo'; // 0

optional chaining operator#

可以視為物件取用屬性時 . 的強化版,使用 ?. 當左側的屬性不存在,即使繼續取用內部屬性也不會噴錯,而是得到 undefined

const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah',
},
};
const dogName = adventurer.dog?.name;
dogName; // undefined,若 dog 屬性不存在
adventurer.someNonExistentMethod?.(); // undefined,若 someNonExistentMethod 方法不存在

可以搭配 nullish coalescing operator 使用:

const dogName = adventurer.dog?.name ?? 'Daniel';
console.log(dogName); // 'Daniel'

delete#

/**
* delete
* 假如 delete 運算子使用成功, 它會將物件或是 property 設定為 undefined。 delete 運算子會在運算成功時回傳 true ,失敗時回傳 false 。
* 一般定義的物件是無法用 delete 刪除(你可以用 delete 運算子來刪除隱式宣告的變數, 但不適用於宣告過的變數。)
* 因此比較適合用來刪除物件屬性
**/
delete objectName; // 宣告過就無法透過 delete 刪除
delete objectName.property; // 可以刪除
delete objectName[index];
/**
* object instanceof constructor
* 看看 object 是否為 constructor 所建構的實例
**/
function Foo() {}
const bar = new Foo();
console.log(bar instanceof Foo);

其他#

typeof#

/**
* typeof 運算元;typeof (運算元)
**/

instanceof#

/**
* object instanceof constructor
* 看看 object 是否為 constructor 所建構的實例
**/
function Foo() {}
const bar = new Foo();
console.log(bar instanceof Foo);

參考#

運算式與運算子 @ MDN

Last updated on