iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0

https://i.imgur.com/4HWQD5Q.jpg

組件實作 : Demo

一、前言

關於 JavaScript 的故事其實是這樣的:「JavaScript 誕生於 1995 年的景網通訊(Netscape Communications),原本的 JavaSciprt 存在於 Netscape 的瀏覽器內運行,直到 2010 年左右 Chrome、Firefox、IE、Safari 開始崛起,Netscape 逐漸式微,瀏覽器這時進入了混亂時期,此時有一間名為 ECMA 的公司 ,這間公司跳出來制定一套瀏覽器標準,此標準被命名為 ECMAScript,相關標準的命名方式,例如 ES5 就是指 ECMAScript 5,而 ECMAScript 6 就會是指 ES6,因為 ES6 的誕生在 2015 年,所以,ES6 也被稱為 ES2015」。

關於 JavaScript 的歷史故事還挺有趣的,可以參考這篇【1】


二、ES6 的主要語法 - Part 1

往後的 ECMAScript 在 ES6 之後幾乎是每年更新一個版本,根據 Wiki 上的資訊顯示【2】,直到目前為止,最後的更新為 ECMAScript 2020(ES2022),第 13 版。這裡先介紹 ES6 的相關語法【3】。

你或許會有一個疑惑,明明 ECMAScript 更新到了 ES13,但是為什麼時常被拿出來討論的卻會是 ES6 呢?其實是因為 ES6 的更新對於 JavaScript 來說,是一種劃時代的大躍進,很多重要的語法,例如 let、const、Arrow Function 都是在這時候出現的,所以,ES6 是最常被拿出來討論版本,其重要性不言而喻。最後,這裡整理一個表格,可用來簡單了解 JS ES6 多了些什麼功能。那就往下看吧~

語法 說明 用途
let 變數 解決變數 var 的 提升問題。
const 常數 使用在像是 ? =3.14 這類型固定常數。
Arrow Function 箭頭函式 簡化 Function 的寫法。
For/of 一種 Loop 取得陣列或字串的各別內容。
Map object 陣列(arrray) 的 map() 方法 遍歷陣列元素,元素傳入指定 Function,最後返回值組成新陣列。
Set object 集合物件 在物件中存放值。
Classes class 用法 class 裡面會加入一個constructor()。
Promises 非同步多執行緒 取代原生 JavaScript 的語法。
Symbol 獨一無二的值 效果類似 CSS 的!important,可用來取代某些變數。
Default Parameter Values 允許 Function 自帶參數 Function 可以添加預設的參數。例如,function fnParameter(x, y = 10, z = "55") {}:
Parameter Rest …args 函式內參數個數不確定,可用「… 變數名稱」取代不定數量的參數。
String.includes() 判別是否有相同單字 字串中有相同單字,則回傳 True,否則回傳 False。
String.startsWith() 判別字首是否為相同單字 字首有相同單字,則回傳 True,否則回傳 False。
String.endsWith() 判別字尾是否為相同單字 字尾有相同單字,則回傳 True,否則回傳 False。
Array.from() 字串轉成陣列 轉陣列是以字元完單位。
Array keys() 取得陣列的所有索引值 可以使用 For/of 個別印出索引值。
Array find() 陣列中查找,找到時,返回內容 找到相同單字時,會回傳該陣列內容,find 找到第一個就會結束查找。
Array findIndex() 陣列中查找,找到時,返回內容的索引值 功能與 Array find() 相似,只是回傳內容為陣列的索引值。

2.1 let 和 const

letvar最大的差別在於,let 不能夠重複的宣告變數,意思為相同變數名稱不能重複定義數值,否則編輯器會有錯誤訊息。

JavaScript:

let x = "Anthony Edward Stark";
let x = 0;  //Error

顯示結果:(錯誤訊息)

Uncaught SyntaxError: Identifier 'x' has already been declared 
 at https://cdpn.io/cpe/boomboom/pen.js?key=pen.js-fa6765f9-ae82-248a-66a9-72f4a958487d:3

let不能夠同時使用同一個變數當作宣告,否則會出現錯誤訊息。

const可用來固定某變數的數值,也就是說,當變數的值被修改後,程式執行時就會有錯誤訊息,以下則使用PI = 3.141592653589793來做測試。

JavaScript:

// const
const PI = 3.141592653589793;
PI = 3.14; // Error
console.log(PI);

顯示結果:(錯誤訊息)

Uncaught TypeError: Assignment to constant variable. 
 at https://cdpn.io/cpe/boomboom/pen.js?key=pen.js-0b2c7564-cef9-e139-277b-7b4539a431c6:3

可以很明顯的看到錯誤訊息「TypeError: Assignment to constant variable.」,當PI的值被修改成3.14後,程式會報錯。

2.2 Arrow Function

箭頭函式也可說是懶人的救星,因為 function 字數太多,讓程式碼看起來太過冗長,也要打很多字,覺得很煩,於是用括號來取代 function 的箭頭函式就是要用來簡化程式碼,相關的用法如下。

原始寫法。

JavaScript:

var theArrow = function (a, b) {
	return a * b;
};
console.log(theArrow(5, 6));

顯示結果:

30

最基本的箭頭函式可以用小括號改寫,如下程式碼。

JavaScript:

let theArrow = (a, b) => a * b;
console.log(theArrow(5, 6));

顯示結果:

30

可以看到顯示結果都一樣。把 function 和 return 省略後,箭頭函式從原本的 4 行變成 2 行。再來介紹一個簡短寫法:假設現在只有使用一個變數a,並且只有執行簡單的運算,例如 a = a + 10,現在能把小括號也一起給省略,程式碼如下。

JavaScript:

var theArrow = a => a + 10;
console.log(theArrow(7));

顯示結果:

17

小括號能夠省略的時機,就是在函式裡的參數只有 1 個的時候可以省略。另外,這裡變數用 var 只是因為方便,你也可以用 let 來替換。當我們知道 Arrow Function 的基本用法後,可能需要額外知道 this 在 Arrow Function 內的用法,這邊先不介紹 this,因為我有可能會誤導?直接附上參考資料。

參考資料:

  1. [JS] 箭頭函式(arrow function)和它對this 的影響 - PJCHENder
  2. Arrow function expressions - JavaScript - MDN Web Docs
  3. 鐵人賽:箭頭函式(Arrow functions) - 卡斯伯Blog - 前端
  4. Function 內的this 到底是哪個this - start from here

2.3 For/of

可以直接針對陣列或是字串內部取出字元來使用。

JavaScript:

// For/of Loop
let str = "The best language is JavaScript.";
let text = "";

for (let x of str) {
	text += x + "-";
}
console.log(text);

顯示結果:

"T-h-e- -b-e-s-t- -l-a-n-g-u-a-g-e- -i-s- -J-a-v-a-S-c-r-i-p-t-.-"

2.4 Map

Map 其實就是針對陣列內容各別做處理。最後會回傳一個新的陣列。

特性:

  1. Map返回值可以讓Key不重複 。
  2. map()返回值會是一個新的陣列。

Key 指的是指陣列中的[“Key” : Value]

JavaScript:

//Map
const animal = new Map([
	["cat", 1000],
	["Dog", 1500],
	["Bird", 500],
	["cat", 1800],
	["cat", 1000]
]);

console.log(animal.get("cat"));
for (let x of animal) {
	console.log(x);
}

顯示結果:

1000
// [object Array] (2)
["cat",1000]
// [object Array] (2)
["Dog",1500]
// [object Array] (2)
["Bird",500]

其他參考:

  1. 現代 [JavaScript] 程式設計教學:使用映射 (Map) 和集合 (Set)
  2. [JS] JavaScript Map
  3. JavaScript Map Object
  4. Day13【ES6 小筆記】Array.map() - 處理陣列最佳選擇
  5. JavaScript ES6 Map and WeakMap Object 物件

2.5 Set

JavaScript 的集合寫法,可以對集合做各種設定,例如 add()has()delete() 等等。

JavaScript:

//Set
let setText = new Set();
setText.add("cat");
setText.add("dog");
setText.add("bird");

console.log(setText);

顯示結果:

// [object Set] (3)
{"cat","dog","bird"}

其他參考:

  1. [JS] JavaScript 集合(Set)
  2. Set - JavaScript - MDN Web Docs - Mozilla

2.6 Classes

JavaScript 的 class 語法的寫法,通常在 class 裡面會加入一個constructor()的 Function。

JavaScript:

// Classes(類)
class Student {
	constructor(name, age, id) {
		this.name = name;
		this.age = age;
		this.id = id;
	}
}

let student1 = new Student("Peter", 18, "N10001");
let student2 = new Student("Marry", 16, "N20001");
console.log(
	student1.name + "'s age is " + student1.age + " ,id is " + student1.id
);

顯示結果:

"Peter's age is 18 ,id is N10001"

其他參考:

  1. JavaScript | ES6 中最容易誤會的語法糖 Class - 基本用法
  2. Classes - JavaScript - MDN Web Docs

2.7 Promises

JavaScript 在處理資料時,採用的運作方式為單一執行緒(tread),也就是同步,這裡的同步是指一次只能做一件事情,但是想要處理其它的程序,比方說想要讀取某個網站的資料,這時後使用同步的方式做處理效率太慢了,因此有了非同步,也就是一次可以同時做好幾件事情的方式來增加效率。而Promise就是一種非同步方式,其實Promise出現之前,JavaScript 本身已經有非同步的處理方式,但是語法結構設計不佳,因此才會有Promise的用法出現,而下面的程式碼為Promise呼叫 Random API 的 User 的範例。

HTML:

<h2>JavaScript Promise</h2>
<p id="demo"></p>

JavaScript:

// Promise
function fnDisplayer(some) {
	document.getElementById("demo").innerHTML = some;
}
let thePromise = new Promise(function (theResolve, theReject) {
	let req = new XMLHttpRequest();
	req.open("GET", "https://random-data-api.com/api/v2/users");
	req.onload = function () {
		if (req.status == 200) {
			theResolve(req.response);
		} else {
			theReject("File not Found");
		}
	};
	req.send();
});

thePromise.then(
	function (value) {
		fnDisplayer(value);
	},
	function (error) {
		fnDisplayer(error);
	}
);

顯示結果:

https://i.imgur.com/l9EMCvD.jpg

其他參考:

  1. JavaScript Promise 全介紹
  2. JavaScript Promises
  3. JavaScript Promises:簡介
  4. Random Data Generator
  5. 程序(進程)、執行緒(線程)、協程,傻傻分得清楚!
  6. [JavaScript] 一次搞懂同步與非同步的一切:一次做幾件事情 — 同步(Sync)與非同步(Async)

三、ES6 的主要語法 - Part 2

3.1 Symbol

Symbol 是 ES6 新增的資料型態,原本 JavaScript 的資料型態有六種(Boolean、Null、Undefined、Number、Object、String),而第 7 種 Symbol,可以理解成獨一無二的值,其用法如下程式碼。

特色:

  1. 唯一的值,可避免命名衝突。
  2. 不能與其他數據做運算、比較

JavaScript:

// Symbol
const person = {
	firstName: "Anya",
	lastName: "Forger",
	age: 5,
	hairColor: "pink"
};

let lastname = Symbol("id");
person[lastname] = "Williams";
console.log(person.lastname);	//undefined
console.log(person[lastname]);	//Williams

顯示結果:

undefined
"Williams"

可以看到person.lastname顯示為undefined,這代表 Symbol 已經有了作用,Symbol 成功的替代person.lastname,這也就代表,我們可以在不去變動原有程式的情況下,使用 Symbol 去設定一個名稱(也就是 id)和要賦予的值(也就是 "Williams"),然後就可以替換掉原來的 key 和 value ,此功能有點像是 CSS 的!important強制替換的感覺。

其他參考:

  1. [JS] Symbols 的使用
  2. JavaScript 的資料型別與資料結構 - MDN Web Docs
  3. 15 尚硅谷 ES6 Symbol的介紹與創建
  4. 16 尚硅谷 ES6 對象添加Symbol類型的屬性

3.2 Default Parameter Values

可以直接在 function 中帶入參數值,舉例來說,可以在fnParameter中帶入y = 10z = "55",以及x帶入7, 回傳出來的值會是三個數值相加,也就是"1755",程式碼如下。

JavaScript:

// Default Parameter Values
function fnParameter(x, y = 10, z = "55") {
	// y、Z 為 function 自帶參數
	return x + y + z;
}
console.log(fnParameter(7));

顯示結果:

"1755"

3.3 多個 Parameter 帶入 Function 的方法(…args)

若 Function 有有多個參數需要被帶入,也就是沒有固定參數的個數,可以使用…args這種寫法來取代多個參數。

// Function Rest Parameter
function fnParameterRest(...args) {
	let sum = 0;
	for (let arg of args) sum += arg;
	return sum;
}
console.log(fnParameterRest(7, 8, 11, 25, 66));

顯示結果:

117

3.4 String 方法

有三個方法可使用,分別為:

  1. String.includes()
  2. String.startsWith()
  3. String.endsWith()

String.includes()指的是一個字串中包含某個單字,若比對相同,回傳值則為true,否則為false

JavaScript:

let theText = "Keep on going never give up.";
console.log(theText.includes("never")); //true
console.log(theText.includes("world"));	//false

顯示結果:

true
false

接著是,兩個可以放在一起比較的東西。

String.startsWith()指的是字串開頭為某個單字,若比對相同,回傳值則為true,否則為false

String.endsWith()指的是字串結尾為某個單字,若比對相同,回傳值則為true,否則為false

JavaScript:

let theText = "Keep on going never give up.";

console.log(theText.startsWith("Keep"));	//true
console.log(theText.startsWith("never"));	//false

console.log(theText.endsWith("Keep")); 	//false
console.log(theText.endsWith(".")); 	//true

顯示結果:

true
false
false
true

其他參考:

  1. String.prototype.startsWith() - JavaScript - MDN Web Docs

3.5 Array 方法

Array 可以使用下列方法:

  1. Array.from()
  2. Array keys()
  3. Array find()
  4. Array findIndex()

Array.from()是將字串轉成陣列的方法。注意它是將字串分割成字元來處理。

JavaScript:

const theArr = Array.from("Keep on going never give up.");
console.log(theArr);

顯示結果:

// [object Array] (28)
["K","e","e","p"," ","o","n"," ","g","o","i","n","g"," ","n","e","v","e","r"," ","g","i","v","e"," ","u","p","."]

Array keys()是用來取出陣列元素索引值的方法。可留意空字串也算是一個索引。

JavaScript:

// Array keys()
const students = ["Tony", "Harry", "Snorlax", "Uta", ""];
const keys = students.keys();

for (let x of keys) {
	console.log(x);
}

顯示結果:

0
1
2
3
4

Array find()的用途找尋陣列中符合條件的值。找到一筆符合的值便會結束查詢,並且回傳查到的值。

JavaScript:

// Array find()
const numbers = [4, 9, 16, -5, 29];
let first = numbers.find(fnFind);

console.log("First number over 18 is " + first);

function fnFind(value, index, array) {
  return value > 18;
}

顯示結果:

"First number over 18 is 29"

Array findIndex()的用法跟Array find()相似,差別在於findIndex()取得值是索引值,你可以與find()直接比較,它們使用相同的判斷方式,也就是說,索引值 4 的值為 29。

JavaScript:

// Array findIndex()
const theNumber = [4, 9, 16, -5, 29];
let theFirst = theNumber.findIndex(fnFindIndex);

function fnFindIndex(value, index, array) {
	return value > 18;
}

console.log("First number over 18 is " + theFirst);

顯示結果:

"First number over 18 is 4"

四、推薦資源

  1. 超好上手的 ES6,學會你都覺得好棒棒
  2. JavaScript 進階: ES6
  3. 詳解JavaScript ES6~11新語法
  4. [ 筆記 ] JavaScript - ES6語法
  5. [ES6] Javascript 開發者必須知道的 10 個新功能
  6. JS ES6~11
  7. es6-cheatsheet
  8. ES6 語法中有什麼新東西?
  9. 淺談 ECMAScript 與 JavaScript
  10. JavaScript - 為什麼 ES6 總是特別拿出來提?
  11. JavaScript、ES6、ES7、ES10 我們在哪裡?
  12. Brief History of JavaScript

五、結論

JavaScript ES6 有很多方法(語法糖)可使用,因為東西有點多,可能沒辦法全部的細節都梳理過一遍,對於這一點感到些許的小遺憾。不過,我在每個主要語法的底下,都有附上額外的參考資料,若是文章中有我寫的不夠清楚地方,可以直接參考資料來補足語法的相關概念。

本篇還有一些方法尚未介紹,像是數學相關的語法,以及重要的 Modules【4】【5】,找時間再補上吧...


六、參考資料

  1. JavaScript 是什麼?認識JS的起源與前世今生
  2. ECMAScript (wiki)
  3. JavaScript ES6 - W3Schools
  4. 完全解析 JavaScript import、export
  5. 模組系統· 從ES6開始的JavaScript學習生活

上一篇
Day 13:Vim 學習筆記
下一篇
Day 15:偽元素與偽類
系列文
手刻武器庫,30 天前端學習心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言