一,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物件的方法一一對應