由於篇幅太長了, 將 ES6 新語法測試拆分成三部分, 這是第二部分.
本系列之前的文章參考 :
參考書籍 :
# Javascript 函數活用範例速查辭典 (博碩 2015, 山田祥寬)
# Javascript Tensorflow.js 人工智慧教本 (碁峰 2020, 陳會安)
4. 解構指定 (destructing assignment) :
所謂解構指定就是指定敘述可以一次對多個變數賦值, Python 就有這個方便語法, 又稱為多重指定 (multiple assignment), 例如 :
a, b, c=1, True, "Hello"
這敘述可以同時將 1 指派給 a, True 指派給 b, "Hello" 指派給 c. 有了這語法, 在 Python 要將兩個變數交換就很簡單, 不需要透過一個中間變數暫存, 只要一條敘述就解決 :
x, y=y, x
Javascript 在 ES6 也添加了這項功能, 其語法為 :
let [x1. x2. x3, ...]=[a1, a2, a3, ...]
等號兩邊個數不一定要相同, 若左邊比右邊少, 則右邊多出來的會被丟棄 (不會有語法錯誤); 反之, 若左邊的比右邊多, 則左邊多出來的變數其值為 undefined. 若要避免出現 undefined, 可在左邊的變數設定預設值, 例如 :
let [x, y=0, z='a']=[1, 2] //x=1, y=2, z='a'
也可以用逗號將對應的變數跳過去不承接, 例如 :
let [x, , z]=[1, 2, 3] //x=1, z= 3, 其中 2 無變數承接
如果兩變數要交換, 語法如下 :
[x, y]=[y, x]
例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
let [a, b, c, d]=[1, 2, 3, 4];
document.write("[a, b, c, d]=[1, 2, 3, 4]" + "<br>");
document.write("a=" + a + "<br>"); //a=1
document.write("b=" + b + "<br>"); //b=2
document.write("c=" + c + "<br>"); //c=3
document.write("d=" + d + "<br>"); //d=4
[a, b, c, d]=[d, c, b, a];
document.write("[a, b, c, d]=[d, c, d, a]" + "<br>");
document.write("a=" + a + "<br>"); //a=4
document.write("b=" + b + "<br>"); //b=3
document.write("c=" + c + "<br>"); //c=2
document.write("d=" + d + "<br>"); //d=1
[a, b=0, c='a', d]=[1, 2]; //設定預設值
document.write("[a, b=0, c='a', d]=[1, 2]" + "<br>");
document.write("a=" + a + "<br>"); //a=1
document.write("b=" + b + "<br>"); //b=2 (有指定, 不使用預設值)
document.write("c=" + c + "<br>"); //c='a' (無指定, 使用預設值)
document.write("d=" + d + "<br>"); //d=undefined (沒有預設值, 多出來的變數)
</script>
</body>
</html>
結果如下 :
[a, b, c, d]=[1, 2, 3, 4]
a=1
b=2
c=3
d=4
[a, b, c, d]=[d, c, d, a]
a=4
b=3
c=2
d=1
[a, b=0, c='a', d]=[1, 2]
a=1
b=2
c=a
d=undefined
a=1
b=2
c=3
d=4
[a, b, c, d]=[d, c, d, a]
a=4
b=3
c=2
d=1
[a, b=0, c='a', d]=[1, 2]
a=1
b=2
c=a
d=undefined
解構指定也可以用在字串, 將字串解構指定給多個變數時, 字串將以字元為單位拆解依序指定給左方的多個變數, 例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
let [a, b, c, d, e, f, g]="Hello World";
document.write("[a, b, c, d, e, f, g]='Hello World'" + "<br>");
document.write("a=" + a + "<br>");
document.write("b=" + b + "<br>");
document.write("c=" + c + "<br>");
document.write("d=" + d + "<br>");
document.write("e=" + e + "<br>");
document.write("f=" + f + "<br>");
document.write("g=" + g + "<br>");
[a, , c, , e, , g]="Hello World";
document.write("[a, , c, , e, , g]='Hello World'" + "<br>");
document.write("a=" + a + "<br>");
document.write("c=" + c + "<br>");
document.write("e=" + e + "<br>");
document.write("g=" + g + "<br>");
</script>
</body>
</html>
此例中第二次解構指定跳過了 b, d, f 變數不予承接, 結果如下 :
[a, b, c, d, e, f, g]='Hello World'
a=H
b=e
c=l
d=l
e=o
f=
g=W
[a, , c, , e, , g]='Hello World'
a=H
c=l
e=o
g=W
a=H
b=e
c=l
d=l
e=o
f=
g=W
[a, , c, , e, , g]='Hello World'
a=H
c=l
e=o
g=W
5. 樣板字串內插 :
Python 有很好用的字串內插功能, 可在字串中嵌入變數或運算式達到動態更改字串局部內容的功能. ES6 也支援這種功能, 這種字串外面不是用單引號或雙引號括起來, 而是使用反引號 (即 Tab 鍵上方那個按鍵), 變數或運算式使用 ${variable|expression} 方式嵌入字串中, 例如 :
let msg=`Hello ${name} !`
這種字串又稱為樣版字面值 (template literals) 或樣版字串 (template string).
例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
let name="Tony";
let msg=`Hello ${name} !` //嵌入變數
document.write(msg + "<br>");
let [a, b, c, d]=[1, 2, 3, 4];
msg=`Math.max(1, 2, 3, 4)=${Math.max(a, b, c, d)}`; //嵌入運算式
document.write(msg + "<br>");
</script>
</body>
</html>
結果如下 :
Hello Tony !
Math.max(1, 2, 3, 4)=4
Math.max(1, 2, 3, 4)=4
6. 展開運算子 :
ES6 新增了三個連續點號 ... 的運算子稱為展開運算子 (spread operator), 它可用在陣列或字串上, 其用途如下 :
- 展開陣列元素
- 複製, 串接, 合併陣列
- 將字串之字元展開變成陣列
- 展開陣列元素後傳入函式做為位置參數
例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
let arr1=[1, 2, 3, 4, 5];
document.write(arr1 + "<br>"); //直接輸出陣列內容
document.write(...arr1 + "<br>"); //輸出展開後的陣列內容
let arr2=[...arr1]; //複製陣列 arr1 為 arr2=arr1.concat()
document.write(...arr2 + "<br>");
let arr3=[11, 12, ...arr1, 13, 14]; //展開後插入到其他陣列中
document.write(...arr3 + "<br>");
let arr4=[...arr1, ...arr2]; //串接兩個陣列=arr1.concat(arr2)
document.write(...arr4 + "<br>");
let arr5=[[1, 2, 3], [4, 5, 6]]; //二維陣列
let arr6=[...arr5]; //複製二維陣列
document.write(arr6 + "<br>");
document.write(...arr6 + "<br>"); //展開二維陣列
let str="你在說哈囉嗎?";
let arr7=[...str]; //展開字串中的每一字元
document.write(...arr7 + "<br>");
</script>
</body>
</html>
此例演示了展開運算子在陣列與字串上的操作, 高維陣列一樣可展開, 結果如下 :
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
11,12,1,2,3,4,5,13,14
1,2,3,4,5,1,2,3,4,5
你,在,說,哈,囉,嗎,?
1,2,3,4,5
1,2,3,4,5
11,12,1,2,3,4,5,13,14
1,2,3,4,5,1,2,3,4,5
你,在,說,哈,囉,嗎,?
輸出在網頁上結果看起來似乎有展開跟沒展開一樣, 輸出到控制台就可看出差異, 例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
let arr1=[1, 2, 3, 4, 5];
console.log(arr1);
document.write(...arr1 + "<br>");
let arr2=[...arr1];
console.log(...arr2);
let arr3=[11, 12, ...arr1, 13, 14];
console.log(...arr3);
let arr4=[...arr1, ...arr2];
console.log(...arr4);
let arr5=[[1, 2, 3], [4, 5, 6]];
let arr6=[...arr5];
console.log(arr6);
console.log(...arr6);
let str="你在說哈囉嗎?";
let arr7=[...str];
console.log(...arr7);
</script>
</body>
</html>
此例與上例差別僅在於輸出到控制台 (console) 而已, 結果如下 :
可見二維陣列直接輸出與展開後再輸出是不一樣的, 點前面的箭頭可顯示其差異 :
展開運算子也可以用來將陣列元素展開後傳入函式做為位置參數, 例如 :
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>ES6 測試</title>
</head>
<body>
<script>
function get_sum(a, b, c) {
return a + b + c;
}
let arr=[1, 2, 3];
let sum=get_sum(...arr); //將陣列元素展開後傳入函式中
document.write("sum=" + sum + "<br>");
</script>
</body>
</html>
結果如下 :
sum=6
沒有留言:
張貼留言