譯20個JS簡寫小技巧,助你高效敲程式碼

作者:Amitav Mishra

譯者:尷尬風流

原文連結:20 JavaScript Shorthand Techniques that will save your time

個人翻譯,轉載請註明出處

The shorthand techniques of any programming language help you to write more clean and optimized code and lets you achieve your goal with less coding. Let』s discuss some of the shorthand techniques of JavaScript one by one.

任何一種程式設計語言的簡寫小技巧都是為了幫助你寫出更簡潔、更完善的程式碼,讓你用更少的編碼實現你的需求。接下來讓我們逐一討論一下JavaScript中的一些簡寫小技巧。

1. 宣告多個變數

1
2
3
4
5
6
// 常規寫法
let x;
let y = 20;

// 簡寫
let x, y = 20;

2. 為多個變數賦值

We can assign values to multiple variables in one line with array destructuring.

我們可以使用陣列解構賦值,僅用一行程式碼實現為多個變數賦值。

1
2
3
4
5
6
7
8
// 常規寫法
let a, b, c;
a = 5;
b = 8;
c = 12;
 
// 簡寫
let [a, b, c] = [5, 8, 12];

3. 恰當使用三元運算子

We can save 5 lines of code here with ternary (conditional) operator.

我們可以在這裡用三元運算子(也稱三元運算子)節省5行程式碼。

1
2
3
4
5
6
7
8
9
10
// 常規寫法
let marks = 26;
let result;
if(marks >= 30){<!-- -->
 result = 'Pass';
}else{<!-- -->
 result = 'Fail';
}
// 簡寫
let result = marks >= 30 ? 'Pass' : 'Fail';

4. 指定預設值

We can use OR(||) short circuit evaluation to assign a default value to a variable in case the expected value found falsy.

我們可以使用「OR ( || ) 短路求值」的邏輯,來給定一個預設值。當 || 我們的期望值是一個「falsy」值的時候,整個運算式的值便會取到我們給定的預設值。

1
2
3
4
5
6
7
8
9
10
11
// 常規寫法
let imagePath;
let path = getImagePath();
if(path !== null && path !== undefined && path !== '') {<!-- -->
  imagePath = path;
} else {<!-- -->
  imagePath = 'default.jpg';
}

// 簡寫
let imagePath = getImagePath() || 'default.jpg';

5. AND(&&)短路求值

If you are calling a function only if a variable is true, then you can use AND(&&) short circuit as an alternative for this.

如果你只在一個變數為真的情況下才呼叫某個函式,那麼你可以用「AND(&&)短路求值」的邏輯來代替。

1
2
3
4
5
6
7
// 常規寫法
if (isLoggedin) {<!-- -->
 goToHomepage();
}

// 簡寫
isLoggedin && goToHomepage();

The AND(&&) short circuit shorthand is more useful in React when you want to conditionally render a component. For example:

在React中,當你想有條件地渲染某個套件時,可以嘗試使用AND(&&)這種簡寫方式。例如下面這個範例??

1
<div> {<!-- --> this.state.isLoading && <Loading /> } </div>

譯者註:運算式的值為0這種特殊的falsy值時,請謹慎考慮使用

6. 交換兩個變數的值

To swap two variables, we often use a third variable. We can swap two variables easily with array destructuring assignment.

當我們想交換兩個變數的值時,經常會採取引入第三個變數的方法。其實我們可以透過陣列解構賦值輕鬆地交換兩個變數。

1
2
3
4
5
6
7
8
9
let x = 'Hello', y = 55;

// 常規寫法,引入第三個變數
const temp = x;
x = y;
y = temp;

// 簡寫,使用陣列解構賦值
[x, y] = [y, x];

7. 善用箭頭函式

1
2
3
4
5
6
7
// 常規寫法
function add(num1, num2) {<!-- -->
   return num1 + num2;
}

// 簡寫
const add = (num1, num2) => num1 + num2;

參考「箭頭函式」

8. 模板字串

We normally use + operator to concatenate string values with variables. With ES6 template literals we can do it in a more simple way.

我們通常使用+運算子來連接字串和其他型別的變數。有了ES6模板字串,我們可以用更簡單的方式來組合字串。

1
2
3
4
5
// 常規寫法
console.log('You got a missed call from ' + number + ' at ' + time);

// 簡寫
console.log(`You got a missed call from ${<!-- -->number} at ${<!-- -->time}`);

9. 多行字串

For multiline string we normally use + operator with a new line escape sequence (
). We can do it in an easier way by using backticks (`)

對於多行字串,我們通常使用+運算子和一個新的換行符(
)拼接實現。其實我們可以透過使用反引號(`)來更簡單地實現。

1
2
3
4
5
6
7
8
9
10
11
// 常規寫法
console.log('JavaScript, often abbreviated as JS, is a
' +            
            'programming language that conforms to the
' +
                        'ECMAScript specification. JavaScript is high-level,
' +
                        'often just-in-time compiled, and multi-paradigm.' );

// 簡寫
console.log(`JavaScript, often abbreviated as JS, is a programming language that conforms to the ECMAScript specification. JavaScript is high-level, often just-in-time compiled, and multi-paradigm.`);

10. 多條件檢查

For multiple value matching, we can put all values in array and use indexOf() or includes() method.

對於多值匹配,我們可以把所有的值放在陣列中,使用陣列提供的indexOf()includes()方法來簡寫。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 常規寫法
if (value === 1 || value === 'one' || value === 2 || value === 'two') {<!-- -->
     // 執行一些程式碼
}

// 簡寫1
if ([1, 'one', 2, 'two'].indexOf(value) >= 0) {<!-- -->
    // 執行一些程式碼
}
// 簡寫2
if ([1, 'one', 2, 'two'].includes(value)) {<!-- -->
    // 執行一些程式碼
}

11. 物件屬性分配

If the variable name and object key name is same then we can just mention variable name in object literals instead of both key and value. JavaScript will automatically set the key same as variable name and assign the value as variable value.

如果變數名和物件的屬性名相同,那麼我們可以在物件的中只寫變數名,而不用同時寫出屬性名和屬性值(變數的值)。JavaScript會自動將屬性名設定為與變數名相同,並將屬性值分配為變數值。

1
2
3
4
5
6
7
8
let firstname = 'Amitav';
let lastname = 'Mishra';

// 常規寫法
let obj = {<!-- -->firstname: firstname, lastname: lastname};

// 簡寫
let obj = {<!-- -->firstname, lastname};

12. 字串(String)轉為數值(Number)

There are built in methods like parseInt and parseFloat available to convert a string to number. We can also do this by simply providing a unary operator (+) in front of string value.

有一些內建方法,如 parseIntparseFloat ,可以將字串轉換為數值。我們也可以透過簡單地在字串值前面提供一個一元運算子 + 來實現。

1
2
3
4
5
6
7
// 常規寫法
let total = parseInt('453');
let average = parseFloat('42.6');

// 簡寫
let total = +'453';
let average = +'42.6';

13. 多次重複一個字串

To repeat a string for a specified number of time you can use a for loop. But using the repeat() method we can do it in a single line.

要將一個字串重複指定的次數,你可以使用for迴圈。但使用repeat()方法,我們可以在一行中完成。

1
2
3
4
5
6
7
8
9
// 常規寫法
let str = '';
for(let i = 0; i < 5; i ++) {<!-- -->
  str += 'Hello ';
}
console.log(str); // Hello Hello Hello Hello Hello

// 簡寫
'Hello '.repeat(5);

Tip: Want to apologize to someone by sending 100 times 「sorry」? Try it with repeat() method. If you want to repeat each string in a new line, then add
to the string.

想對某人說100次對不起?試試 repeat() 方法吧。如果你希望每一個字串佔一行,那麼就在字串結尾新增換行符(
)。

1
2
3
// 想跟你說100聲抱歉!
'sorry
'.repeat(100);

14. 冪的力量!

We can use Math.pow() method to find the power of a number. There is a shorter syntax to do it with double asterik (**).

我們可以使用 Math.pow() 方法來求一個數值的冪。有一個更簡潔的語法,那就是雙星號(**)。

1
2
3
4
5
// 常規寫法
const power = Math.pow(4, 3); // 64

// 簡寫
const power = 4**3; // 64

15. 雙NOT位運算子(~~)?

The double NOT bitwise operator is a substitute for Math.floor() method.

雙NOT位運算子(~~)是 Math.floor() 方法的替代品。

1
2
3
4
5
// 常規寫法
const floor = Math.floor(6.8); // 6

// 簡寫
const floor = ~~6.8; // 6

Improvement from comment by Caleb:
The double NOT bitwise operator approach only works for 32 bit integers i.e (231)-1 = 2147483647. So for any number higher than 2147483647, bitwise operator (~~) will give wrong results, so recommended to use Math.floor() in such case.

感謝Caleb的提醒:
雙NOT位運算子方法
只適用於32位整數**,即(2**31)-1=2147483647。所以對於任何大於2147483647的數值,位運算子(~~)會給出錯誤的結果,所以建議在這種情況下使用Math.floor()。

16. 找出陣列中的最大最小值

We can use for loop to loop through each value of array and find the max or min value. We can also use the Array.reduce() method to find the max and min number in array.

我們可以使用for迴圈來遍歷陣列,找到最大值或最小值。也可以使用Array.reduce()方法來尋找陣列中的最大和最小值。

But using spread operator we can do it in a single line.

但是使用展開運算子(...)我們可以,我們可以用一行程式碼就實現這個需求。

1
2
3
4
// 簡寫
const arr = [2, 8, 15, 4];
Math.max(...arr);  // 最大值 15
Math.min(...arr);  // 最小值 2

17. 關於For迴圈

To loop through an array we normally use the traditional for loop. We can make use of the for…of loop to iterate through arrays. To access the index of each value we can use for…in loop.

要遍歷一個陣列,我們通常使用傳統的 for 迴圈。我們可以利用 for...of 的方式來遍歷一個陣列。如果要訪問陣列每個值的索引,我們可以使用 for...in 迴圈。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let arr = [10, 20, 30, 40];

// 常規寫法,for迴圈
for (let i = 0; i < arr.length; i++) {<!-- -->
  console.log(arr[i]);
}

// 簡寫

// for...of迴圈
for (const val of arr) {<!-- -->
  console.log(val);
}

// for...in迴圈
for (const index in arr) {<!-- -->
  console.log(`index: ${<!-- -->index} and value: ${<!-- -->arr[index]}`);
}

We can also loop through object properties using for…in loop.

我們還可以使用 for...in 迴圈來遍歷物件的屬性。

1
2
3
4
let obj = {<!-- -->x: 20, y: 50};
for (const key in obj) {<!-- -->
  console.log(obj[key]);
}

參考:JavaScript中遍歷物件和陣列的幾種不同的方式

18. 合併陣列

1
2
3
4
5
6
7
8
9
let arr1 = [20, 30];

// 常規寫法
let arr2 = arr1.concat([60, 80]);
// [20, 30, 60, 80]

// 簡寫
let arr2 = [...arr1, 60, 80];
// [20, 30, 60, 80]

19. 多層次物件的深拷貝

To deep clone a multi-level object, we can iterate through each property and check if the current property contains an object. If yes, then do a recursive call to the same function by passing the current property value (i.e. the nested object).

要對一個多層次的物件實現深拷貝,我們可以遍歷其每個屬性,檢查當前屬性是否包含一個物件。如果是,則遞迴呼叫同一個函式,並將當前屬性值(即巢狀物件)作為函式的引數傳遞進去。

We can also do it by using JSON.stringify() and JSON.parse() if our object doesn』t contains functions, undefined, NaN or Date as values.

如果我們的物件不包含函式undefinedNaNDate等值,我們也可以使用 JSON.stringify()JSON.parse() 來實現。

If we have single level object i.e no nested object present, then we can deep clone using spread operator also.

如果我們的物件是單層物件,即沒有巢狀物件,那麼我們也可以使用展開運算子(...)進行深拷貝。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let obj = {<!-- -->x: 20, y: {<!-- -->z: 30}};

// 常規寫法,遞迴
const makeDeepClone = (obj) => {<!-- -->
  let newObject = {<!-- -->};
  Object.keys(obj).map(key => {<!-- -->
    if(typeof obj[key] === 'object'){<!-- -->
      newObject[key] = makeDeepClone(obj[key]);
    } else {<!-- -->
      newObject[key] = obj[key];
    }
  });
 return newObject;
}
const cloneObj = makeDeepClone(obj);

// 特殊情況下(物件中屬性值沒有函式、undefined或NaN的情況下)的簡寫
const cloneObj = JSON.parse(JSON.stringify(obj));

// 單層物件(無巢狀物件)情況下的簡寫
let obj = {<!-- -->x: 20, y: 'hello'};
const cloneObj = {<!-- -->...obj};

Improvement from comment:
The shorthand technique (JSON.parse(JSON.stringify(obj))) doesn』t work if your object property contains function, undefined or NaN as value. Because when you JSON.stringify the object, the property containing function, undefined or NaN as value gets removed from the object.
So use JSON.parse(JSON.stringify(obj)) when your object contains only strings and numbers.

感謝評論區中的提醒:
如果你的物件屬性中包含函式undefinedNaN作為屬性值時,**JSON.parse(JSON.stringify(obj)) **這種簡寫將會失效。因為當你對物件進行 JSON.stringify 時,包含函式、undefined或NaN作為值的屬性會從物件中被刪除。
所以當你的物件只包含字串和數值時,才可以使用 JSON.parse(JSON.stringify(obj))

參考:JSON.parse() 和 JSON.stringify()

20. 取得字串中的某個字元

1
2
3
4
5
6
7
let str = 'jscurious.com';

// 常規寫法
str.charAt(2); // c

// 簡寫
str[2]; // c

Some of these shorthand techniques may not seems relevant to use in project but it』s not bad to know some extra techniques.
這些簡寫小技巧中的一些似乎不太適合在專案中使用,但知道總比不知道強。

Happy coding!

好編碼,編好碼,編碼好!
**

【附】專有名詞總結:

中文 英文
簡寫技巧 shorthand techniques
賦值 assign value
陣列解構賦值 array destructuring assignment
條件運算子 conditional operator
展開運算子 spread operater
深拷貝 deep clone
期望值 expected value
多值匹配 multiple value matching
內建方法 built in method
遞迴呼叫 recursive call
巢狀物件 nested object
模板字串(模板字面量) template literals