系列文章 -- ES6筆記系列
搞ES6的人也是夠無聊,把JS弄得越來越像Java、C++,連Iterator疊代器、Set集合、Map結構都出來了,不知道說什麼好...
一、簡單使用
1. iterator
學過C++的人應該知道這是個疊代器對象,擁有一個指針,指向資料結構中的某個成員
JS中的iterator也有類似的功能,JS内部為一些資料結構實作了iterator疊代器的接口,讓我們可以友善的使用
var [a, b, ...c] = [1, 2, 3, 4];
c // [3, 4]
如上,解構指派以及擴充運算符的便利,多虧了内部實作的預設iterator疊代器接口,可以使用其Symbol.iterator屬性獲得,如
var arr = [1, 2, 3];
var it = arr[Symbol.iterator]();
it.next() // {done: false, value: 1}
it.next() // {done: false, value: 2}
it.next() // {done: false, value: 3}
it.next() // {done: true, value: undefined}
上述的iterator接口表現形式過于隐秘,在generator生成器函數中,我們可以看看比較顯示的iterator接口調用:
function* showNumbers() {
yield 1;
yield 2;
yield 3;
}
var show = showNumbers();
show.next(); // {done: false, value: 1}
show.next(); // {done: false, value: 2
show.next(); // {done: true, value: 3}
通過調用next方法,實作iterator疊代器的周遊
可見結果輸出是一個對象,該對象擁有done這個疊代器是否周遊完成的狀态,以及目前指向項的值
看到這裡,結合上述兩個例子,應該知道可以通過Symbol.iterator與generator的結合,建立出一個iterator疊代器,比如:
var obj = {};
obj[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...obj] // [1, 2, 3]
既然隻有done與value兩個屬性,實作起來應該不是太難,我們可以嘗試實作一個基本的iterator
function myIterator(arr) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < arr.length
? {
value: arr[nextIndex++],
done: false
}
: {
value: undefined,
done: true
}
}
}
}
var it = myIterator(['one', 'two']);
it.next() // {done: false, value: "one"}
it.next() // {done: true, value: "two"}
it.next() // {done: true, value: undefined}
2. Set
Set是ES6中新引入的資料結構,它類似于數組,但是成員的值都是唯一的,沒有重複的值。
可以通過執行個體化其構造函數,用來生成Set資料結構,通過.add()方法插入值,通過for...of循環周遊相應值
var s = new Set();
var arr = [1, 2, 2, 3];
arr.forEach(function(item) {
s.add(item);
});
for (var item of s) {
console.log(item) // 1 2 3
}
可見Set自動去除了重複的值,隻插入了一個2,由此在去除數組重複值的時候,可以更友善:
var arr = [1, 2, 2, 3];
function unique(arr) {
return [...new Set(arr)];
}
unique(arr) // [1, 2, 3]
不過,要注意的是,Set判斷是否重複,是使用到了全等===條件,即類型及值完全相等才擯除,不過NaN是例外
var arr = [1, 0, '', 3, false, 3, NaN, NaN];
function unique(arr) {
return [...new Set(arr)];
}
unique(arr) // [1, 0, '', 3, false, NaN]
set有一些屬性和方法:
-
:構造函數,預設就是Set.prototype.constructor
函數。Set
-
:傳回Set.prototype.size
執行個體的成員總數。Set
-
:添加某個值,傳回Set結構本身。add(value)
-
:删除某個值,傳回一個布爾值,表示删除是否成功。delete(value)
-
:傳回一個布爾值,表示該值是否為has(value)
的成員。Set
-
:清除所有成員,沒有傳回值。clear()
var s = new Set();
s.add(1).add(2).add(2);
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2);
s.has(2) // false
s.clear()
s.has(1) // false
set的一些周遊操作:
-
:傳回鍵名的周遊器keys()
-
:傳回鍵值的周遊器values()
-
:傳回鍵值對的周遊器entries()
-
:使用回調函數周遊每個成員forEach()
keys()、values()、entries()的使用
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
forEach的使用
let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6
set與數組的轉換
數組轉換成set結構隻需要将數組加入到set構造函數參數中執行個體化即可
set集合轉換成數組,可簡單的使用擴充運算符...,也可使用Array.from()的新方法
var items = new Set([1, 2, 3, 4, 5]);
var array1 = Array.from(items);
var array2 = [...items]
array1 // [1, 2, 3, 4, 5]
array2 // [1, 2, 3, 4, 5]
3. Map
Map也是ES6中新引入的資料結構,它類似于Hash結構,屬于鍵=>值對的結構,每一項值可用key=>value來表示
通過執行個體化構造函數生成一個map對象,再通過.set方法設定相關項的鍵值對,通過.get方法擷取相應的鍵值對
var m = new Map();
var obj = {str: 'str'};
m.set(obj, 'content');
m.get(obj) // "content"
也可以直接在構造函數中加入一個數組參數,直接執行個體化出map對象
var map = new Map([
['name', '張三'],
['title', 'Author']
]);
map.size // 2
map.has('name') // true
map.get('name') // '張三''
map.has('title') // true
map.get('title') // 'Author'
類似Set,Map也有一些常見的屬性和方法
- size屬性 傳回Map結構的成員總數。
- set(key, value) 設定
所對應的鍵值,然後傳回整個Map結構。如果key
已經有值,則鍵值會被更新,否則就新生成該鍵key
- get(key) 讀取
對應的鍵值,如果找不到key
,傳回key
。undefined
- has(key) 傳回一個布爾值,表示某個鍵是否在Map資料結構中
- delete(key) 删除某個鍵,傳回true。如果删除失敗,傳回false
- clear() 清除所有成員,沒有傳回值。
類似Set,Map也有一些常見的周遊方法
-
:傳回鍵名的周遊器。keys()
-
:傳回鍵值的周遊器。values()
-
:傳回所有成員的周遊器。entries()
-
:周遊Map的所有成員forEach()
let map = new Map([
['F', 'no'],
['T', 'yes'],
]);
for (let key of map.keys()) {
console.log(key);
}
// "F"
// "T"
for (let value of map.values()) {
console.log(value);
}
// "no"
// "yes"
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"
// 或者
for (let [key, value] of map.entries()) {
console.log(key, value);
}
// 等同于使用map.entries()
for (let [key, value] of map) {
console.log(key, value);
}
Map與數組的轉換
與Set一樣,Map和數組直接也可以互相轉換
使用擴充運算符...可以将Map轉換為數組
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
執行個體化Map構造函數時傳入參數可将數組轉換為Map對象
new Map([[true, 7], [{foo: 3}, ['abc']]])
// Map {true => 7, Object {foo: 3} => ['abc']}
4. WeakSet
...
5. WeakMap
後記:
ES6的内容實在是太多了,打算閱讀相關新特性文檔後做個筆記,蓦然發現經常會不耐煩
文章不知從何寫起,不知如何布局文章内容結構,寫完之後又覺得不夠全面或者了解還未到位,每每想不再繼續
寫到這篇set和map,已經沒啥耐心寫下去了
還是好好看看其他人的總結吧,全面許多
完
[-_-]眼睛累了吧,注意勞逸結合呀[-_-]