一,Symbol
原始資料型別,不是物件,它是JavaScript第七種資料型別,表示獨一無二的值。Symbol是通過Symbol函式生成的:
let s = Symbol(); typeof s
// "symbol"
不用new,因為Symbol不是物件,而是原始值。Symbol通常作為內建的值來使用,最重要的一個屬性:
Symbol.iterator,該屬性指向該物件的預設遍歷器方法,所以
obj[Symbol.iterator]會返回該物件的預設遍歷器,然後可以使用遍歷器一些方法比如for...of
二,Set,Map
1,Set
類似於陣列,但是成員的值都是唯一的,本身是建構函式,所以可以const s = new Set();
Set函式接收一個數組,會進行去重,但是注意返回的是Set結構,不是陣列,因此要轉換一下
[...new Set(array)],這就是最簡單的陣列去重。
Set生成的物件有size屬性(實際是Set.prototype.size屬性),代表裡面成員個數,都是不重複的。
4個操作方法:
add(value),新增某個值,返回Set結構本身,所以可以鏈式使用,連續add,但是如果add都是同一個,其實只算1個
delete(value),刪除某個值,返回布林值,表示是否刪除成功
has(value),返回布林值,表示是否為Set的成員
clear(),清楚所有成員,沒有返回值
4個遍歷方法:
keys():返回鍵名的遍歷器
values():返回鍵值的遍歷器
entries():返回鍵值對的遍歷器,entries不管是陣列操作還是物件操作,還是其他操作,返回的都是['鍵名', '鍵值']這樣的一個一個數組
forEach():使用回撥函式遍歷每個成員
返回遍歷器的通常操作是for...of迴圈返回的遍歷器
利用Set實現陣列的交集,並集和差集。
let arr1 = [1,2,3];
let arr2 = [4,2,1]; let a = new Set(arr1);
let b = new Set(arr2); // 並集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4} // 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// Set {1, 2} // 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {3, 4}
這裡要注意的點:
1,new Set只能傳一個數組,在將a, b合併的時候用擴充套件運算子,外面要包上陣列,
2,擴充套件運算子是適用於所有的具有iterator介面的物件,所以用a,b或者arr1,arr2都一樣。
3,filter是陣列方法,必須要把Set結構先轉為陣列結構
三,Map
JavaScript的物件本質上是鍵值對的集合(Hash結構),但只能用字串作為鍵,而ES6提供的Map結構,類似於物件,也是鍵值對的集合,但是它的鍵不侷限於字串,各種型別的值都可以當作鍵,包括物件,“值-值”
cosnt m = new Map();
const o = {p: 'hello world'}; m.set(o, 'content') m.get(o) // 'content' m.has(o) // true
m.delete(o) // true
m.has(o) // false
注意:
只有對同一個物件的引用,Map結構才將其視為同一個鍵!因為不同物件,記憶體地址是不同的,具體反例:
const map = new Map(); map.set([1], 'content') map.get([1]) // undefined
Map的屬性,方法和遍歷方法跟Set一模一樣。
四,Proxy
Proxy用於修改某些操作的預設行為,說白了,就是在目標物件前面設定一個“攔截層”,外界對該物件的訪問必須先通過這層攔截,起到過濾和改寫,Proxy譯為代理,也就是“代理器”
建構函式Proxy接受兩個引數,第一個是所要代理的目標物件,第二個是一個配置物件,裡面是很多處理函式,就是對該函式攔截對應的操作。
主要的處理函式有:
get(target, propKey, receiver):攔截物件屬性的讀取,你只要訪問物件任何屬性,就會觸發它
set(target, propKey, value, receiver):攔截物件屬性的設定
apply(target, object, args): 攔截例項,只要將其作為函式呼叫的話就會觸發,注意,是作為呼叫
construct(target, args): 攔截作為建構函式呼叫,就是用了new
var handler = {
get: function(target, name){
if (name === 'prototype'){
return Object.prototype;
}
return 'hello' + name
},
apply: function(target, thisBlinding, args) {
return args[0]
},
constructor: function(target, args) {
return {value: args[1]}
}
}; var fproxy = new Proxy(function(x, y){
return x+y
}, handler); fproxy(1, 2) // 1
new fproxy(1, 2) // {value: 2}
fproxy.prototype === Object.prototype // true
fproxy.foo // 'Hello, foo'
五,Reflect
Reflect物件類似於Proxy物件,設計目的:
1,將Object物件的屬於語言內部的方法放到了Reflect物件上,如Object.defineProperty
2,修改某些Object方法的返回結果
3,讓Object操作都變成函式行為
4,Reflect物件的方法與Proxy物件的方法一一對應