ES6的學習筆記

風靈使發表於2019-01-08

ES6

  • ES6的學習筆記and程式碼練習
  • 基於webpack打包

let

在這裡插入圖片描述

const

在這裡插入圖片描述

數值的擴充套件

在這裡插入圖片描述

陣列的擴充套件

在這裡插入圖片描述

解構賦值

在這裡插入圖片描述

函式擴充套件

在這裡插入圖片描述

物件的擴充套件

在這裡插入圖片描述

Set and Map

在這裡插入圖片描述

在這裡插入圖片描述

Promise

在這裡插入圖片描述

0、raceur編譯器

Google公司的Traceur(http://github.com/google/traceur-compiler)編譯器,可以將ES6程式碼編譯為ES5程式碼。
使用方法:直接插入網頁
首先,必須在網頁頭部載入Traceur庫檔案

	<script src = "http://google.github.io/traceur-compiler/bin/traceur.js" type="text/javascript"></script>
	<script src="http://google.github.io/traceur-compiler/src/bootstrap.js" type="text/javascript"></script>
	<script>
		traceur.options.experimental = true;
	</script>
	<script type="module">
		//ES6程式碼
	</script>

type屬性的值是module,這是Traceur用來辨識ES6程式碼的標識,編譯器會自動將所有標記了type=module的程式碼編譯為ES5程式碼,然後交給瀏覽器執行

1、let命令

ES6新增了let命令,用於宣告變數,用let宣告的變數,只在let命令所在的程式碼塊內有效。
let其實是為JavaScript新增了塊級作用域。

2、const命令

const用來宣告常量,一旦宣告,其值就不能改變。
constlet的作用域相同,只在宣告所在的塊級作用域內有效。
const宣告的常量不可重複宣告

3、陣列的解構

ES6允許按照一定模式,從陣列和物件中提取值,對變數進行復制,這被稱為解構

例如 var [a,b,c] = [1,2,3]//本質上屬於模式匹配,只要兩邊的模式相同,左邊的變數就會被賦予相應的值

注意:解構只能用於陣列或者物件。其他原始型別的值都可以轉化為相應的物件,但是undefinednull不能轉化為物件,所以不能夠解構。

物件的解構:

陣列的元素是按照次序排列的,變數的取值由它的位置決定,而物件的屬性沒有次序,變數必須與屬性同名,才能取到正確的值

解構的用途:
(1)交換變數的值
(2)從函式返回多個值

	function example (){
		return [1,2,3];
	}
	var [a,b,c] = example();
(3) 函式引數的定義
	funciton f({x,y,z}){
		//...
	}
	f({x:1,y:2,z:3})
(4) 函式引數的預設值
	jQuery.ajax= function (url,{
		async = true,
		beforeSend = function () {},
		cache = true,
		complete = function () {},
		crossDomain = false,
		global = true.
		}) {
			//...
		}

4、for-of 迴圈

任何部署了Iterator介面的物件,都可以使用for-of迴圈遍歷。

我們如何遍歷陣列中的元素:

(1) for迴圈

	for (var index = 0; index < myArray.length; index++) {
  		console.log(myArray[index]);
	}

(2) forEach方法遍歷陣列

	myArray.forEach(function (value) {
		console.log(value);
	});

(3) for-in迴圈

	for (var index in myArray) { // 千萬別這樣做!!
	    console.log(myArray[index]);
	}

這絕對是一個糟糕的選擇,為什麼呢?
1)在這段程式碼中,賦給index的值不是實際的數字,而是字串“0”、“1”、“2”,此時很可能在無意之間進行字串算數計算,例如:“2” + 1 == “21”,這給編碼過程帶來極大的不便。
2)作用於陣列的for-in迴圈體除了遍歷陣列元素外,還會遍歷自定義屬性。

舉個例子,如果你的陣列中有一個可列舉屬性myArray.name,迴圈將額外執行一次,遍歷到名為“name”的索引。就連陣列原型鏈上的屬性都能被訪問到。
3)最讓人震驚的是,在某些情況下,這段程式碼可能按照隨機順序遍歷陣列元素。
4)簡而言之,for-in是為普通物件設計的,你可以遍歷得到字串型別的鍵,因此不適用於陣列遍歷。

(4)強大的for-of迴圈

	for (var value of myArray) {
	    console.log(value);
	}

1)這是最簡潔、最直接的遍歷陣列元素的語法;
2)這個方法避開了for-in迴圈的所有缺陷 ;
3)與forEach()不同的是,它可以正確響應break、continuereturn語句 ;
4)for-of迴圈也可以遍歷其它的集合,for-of迴圈不僅支援陣列,還支援大多數類陣列物件,例如DOM NodeList物件;
5)for-of迴圈也支援字串遍歷,它將字串視為一系列的Unicode字元來進行遍歷。

5、字串的擴充套件

1、ES6提供了3中新方法來確定一個字串是否包含在另一個字串中:

(1)contains():返回布林值,表示是否找到了引數字串
(2)startsWith():返回布林值,表示引數字串是否在源字串的頭部
(3)endsWith():返回布林值,表示引數字串是否在源字串的尾部

例如:

		var s = "Hello world!";
		s.startsWith("Hell");//true
		s.endsWith("!");//true
		s.contains("o");//true

以上三個函式都支援第二個引數,表示開始搜尋的位置

		s.startsWith("o",4);//true
		s.endsWith("e",2);//true

2、repeat()
返回一個新的字串,表示將原字串重複n

"x".repeat(3);//"xxx"

3、模板字串
模板字串是增強版的字串,用反引號`標識。它可以當作普通字串使用,也可以用來定義多行字串,或者在字串中嵌入變數。

	   //普通字串
		`Hello World`;
		//多行字串
		`Hello
		World!`
		//字串中嵌入變數
		var name = 'Bob',time = "today";
		`Hello ${name},how are you ${time}?`;

在模板字串中嵌入變數,需要將變數名寫在${}中。

6、數值的擴充套件

(1) Number.isFinite()Number.isNaN()
用來檢查InfiniteNaN這兩個特殊值
這兩個方法僅對數值有效,對於非數值一律返回false

		Number.isFinite("25");//false
		isFinite("25");//true

(2) Number.parseInt() ,Number.parseFloat()
ES6將全域性方法parseInt()parseFloat()移植到了Number物件上,這樣做的目的是逐步減少全域性方法,使語言逐步模組化。
(3) Math的擴充套件

Math.trunc() //用於去除一個數的小數部分,返回其整數部分

7、陣列的擴充套件

(1) Array.of()//用於將一組值轉換為陣列

Array.of(1,2,3) //[1,2,3]

(2) find() //用於找出第一個符合條件的陣列元素,它的引數是一個回撥函式,所有陣列元素依次遍歷該回撥函式,直到找出第一個返回值為true的元素,然後返回該元素,否則返回undefined

[1,,5,10,15] .find(function (value,index,arr) {
		return value > 9;
		}) //10

findIndex()//返回第一個符合條件的陣列元素的位置,如果所有元素都不符合,則返回-1

(3) fill() //使用給定值填充一個陣列

(4) 陣列推導

陣列推導:允許直接通過現有陣列生成新陣列。

	var a1 = [1,2,3,4];
	var a2 = [for (i of a1) i*2];//[2,4,6,8]

for of 後面還可以附加if語句,用來設定迴圈的限制條件

	var years = [2000,2004,2008,2012,2016];
	[for (year of years) if (year >2007)];//[2008,2012,2016]
	[for (year of years) if(year>2007&& year<2013)];//[2008,2012]

8、函式的擴充套件

(1) 為函式的引數設定預設值。

		function Point (x=0,y=0) {
			this.x = x;
			this.y = y;
		}

任何帶有預設值的引數,都被是為可選引數,不帶預設值的引數,則被視為必需引數

(2)rest引數
ES6引入了rest引數(…變數名),用於獲取函式的多於引數,rest引數後面不能再有其他引數,否則會報錯。

	function add(...values){
		let sum = 0;
		for(var value of values) {
			sum +=value;
		}
		return sum;
	}
	add(2,5,3);//10

(3)擴充套件運算子…
擴充套件運算子好比rest引數的逆運算,將一個陣列轉換為用逗號分隔的引數序列。

	var a=[1];
	var b=[2,3];
	var c=[4,5,6];
	var d=[0,...a,...b,...c];
	console.log(d);//[0,1,2,3,4,5,6];

(4)箭頭函式=>

	var f = v => v;

等同於:

	var f = function (v) {
		return v;
	};
	var f = () => 5;

等同於:

var f = function (){
		return 5;
	}

簡化函式:

	[1,2,3].map(function(x){
		return x*x;
		});
	//箭頭函式寫法
	[1,2,3].map(x=>x*x);

注意:
函式體內的this物件,繫結定義時所在的物件,而不是使用時所在的物件;
不可以當作建構函式,即不可以使用new命令,否則報錯;
不可以使用arguments物件,該物件在函式體內不存在;

新的知識:
1、如果箭頭函式不需要引數或者需要多個引數,就是用圓括號代表引數部分
例如: var sum (num1,num2) => num1+num2;
2、如果箭頭函式的程式碼塊部分多於一條語句,就要使用大括號將其括起來,並使用return語句返回
3、如果箭頭函式直接返回一個物件,必須在物件外面加上括號。

	var getTempItem = id => ({id:id,name:"Temp"});

由於this在箭頭函式中被繫結,所以不能用call(),apply(),bind()修改this指向

8、SetMap

(1) Set類似於陣列,不過其成員值都是唯一的,沒有重複的值。
Set本身是一個建構函式,用來生成Set資料結構。
例如:

		  	var s = new Set();
		  	[2,3,4,5,5,2,2].map(x => s.add(x));
		  	for(i of s ){
		  		console.log(i);//2,3,4,5
		  	}
		  	//可以用陣列對set進行初始化
		  	var items = new Set([1,2,2,2,2,3]);
		  	console.log(items.size);//3

Set結構的方法:

add(value);
delete(value);
has(value);
clear():清除所有成員

Set結構的屬性:

Set.prototype.constructor:建構函式,預設就是Set函式
Set.prototype.size:返回Set的成員總數
//去除陣列中重複元素
function dedupe (array) {
  return Array.from(new Set(array));
}

(2) Map結構,類似於物件,也是鍵值對的集合,但是,“鍵”的範圍不限定於字串,物件也可以當作鍵。
例如:

		  	var m = new Map();
		  	o = {
		  		p:"Hello World!";
		  	}
		  	m.set(o,"content");
		  	console.log(m.get(o));//content

Map的屬性:

size:返回成員總數;

Map的方法:

set(key,value);
get(key);
has(key);
delete(key);
clear()

Map的遍歷

map.keys():返回鍵名的遍歷器
map.values():返回鍵值的遍歷器
map.entries():返回所有成員的遍歷器

9、Iterator遍歷器

遍歷器是一種協議,任何物件只要部署了這個協議,就可以完成遍歷操作。它的主要作用有兩個,一個是為遍歷物件的屬性提供統一的介面二是物件的屬效能夠按次序排列

ES6的遍歷器協議規定,部署了next方法的物件,就具備了遍歷器功能。next方法必須返回一個包含valuedone兩個屬性的物件。value屬性是當前遍歷位置的值,done屬性是一個布林值,表似乎遍歷是否結束。

			function makeIterator (array) {
				var nextIndex = 0;
				return {
					next: function () {
						return nextIndex < array.length ? {value:array[nextIndex++],done:false}:{value:undefined,done:true};
					}
				}
			}//定義了一個makeIterator函式,作用是返回一個遍歷器物件,用來遍歷引數陣列。

ES6中,一個物件只要部署了next方法,就被視為具有Iterator介面,就可以用for...of迴圈遍歷它的值。

			var it = makeIterator([1,2,3,4,5]);
			for(var n of it) {
				if(n>it.length){
					break;
				}
				console.log(n);
			}

for...in 迴圈讀取鍵名;for...of迴圈讀取鍵值

10、Generator

Generator 就是普通函式,有兩個特徵:一是function關鍵字後面有一個星號;二是函式體內部使用yield語句定義遍歷器的每個成員,即不同的內部狀態

	    function* helloWorldGenerator () {
			yield 'hello';
			yield 'world';
			return 'ending';
		}
		var hw = helloWorldGenerator();
		hw.next();
		hw.next();
		hw.next();

Generator的本質,是提供一種可以暫停執行的函式。

11、Promise

ES6原生提供Promise物件。所謂Promise物件,就是代表了未來某個將要發生的事件(通常是一個非同步操作)。它的好處在於,有了promise物件,就可以將非同步操作的流程表達出來,避免了層層巢狀的回撥函式。

Promise物件的基本用法:

	var promise = new Promise(function(resolve,reject) {
		if(/*非同步操作成功*/) {
			resolve(value);
		} else {
			reject(error);
		}
	});
	promise.then(function (value) {
		//success
	},function(value){
		//failure
	})

以上程式碼表示,Promise 建構函式接受一個函式作為引數,該函式的兩個引數分別為resolve方法和reject方法。如果非同步操作成功,則用resolve方法將Promise物件的狀態變為成功,否則,用reject方法將狀態變為失敗。

promise例項生成以後,可以使用then方法分別制定resolve方法和reject方法的回撥函式。

Promise物件實現Ajax操作:

	var getJSON = function (url) {
		var promise = new Promise (function (resolve,reject) {
			var client = new XMLHttpRequest();
			client.open("GET",url);
			client.onreadystatechange = handler;
			client.responseType = "json";
			client.setRequestHeader("Accept","application/json");
			client.send();
			function handler () {
				if (this.readyState === this.DONE) {
					if(this.status === 200) {
						resolve(this.response);
					} else {
						reject(this);
					}
				}
			}
		});
		return promise;
	};

	getJSON("/post.json").then(function(json){
		//continue
	}, function(error){
		//handle errors
	})

Promise 物件有三種狀態:

(1)Fulfilled 可以理解為成功的狀態
(2)Rejected 可以理解為失敗的狀態
(3)Pending 既不是 Fulfilld 也不是 Rejected 的狀態,可以理解為 Promise 物件例項建立時候的初始狀態

Promise.all 可以接收一個元素為 Promise 物件的陣列作為引數,當這個陣列裡面所有的 Promise 物件都變為 resolve 時,該方法才會返回。

Promise 迷你書:
http://liubin.org/promises-book/

相關文章