ES6 新增數據類型

一辱匿、Symbol


ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值炫彩。它是 JavaScript 語言的第七種數據類型匾七,前六種是:undefinednull江兢、布爾值(Boolean)昨忆、字符串(String)、數值(Number)杉允、對象(Object)邑贴。

注意點:

  1. symbol是一種基本數據類型(非復雜類型)。
  1. 它不支持語法new Symbol()夺颤。
  1. 每個從Symbol()返回的symbol值都是唯一的痢缎。

Symbol的用途

  1. 一個symbol值能作為對象屬性的標識符。
    由于每一個 Symbol 值都是不相等的世澜,這意味著 Symbol 值可以作為標識符独旷,用于對象的屬性名,就能保證不會出現同名的屬性寥裂。
let mySymbol = Symbol();

// 第一種寫法
let a = {};
a[mySymbol] = 'Hello!';

// 第二種寫法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三種寫法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"
image.png
  1. 可以用Symbol來模擬私有屬性
    例如嵌洼,我們可以在一個塊內使用Symbol作為對象的屬性名

這樣在這個塊之外就無法訪問到我們用Symbol定義的屬性

二、Set


ES6 以前實現數組去重(計數排序的邏輯)

function unique(arr) {
    var hashTab = {}
    var newArr
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] in hashTab) {
            // 什么也不做
        } else {
            hashTab[arr[i]] = true
        }
    }
    newArr = Object.keys(hashTab).map(n => n - 0)
    return newArr
}

但這種算法并不完美封恰,它存在兩個缺陷:

  1. 它無法區(qū)分數組中的數字和字符串
  2. 如果數組里有對象麻养,也會影響去重的結果

例如有一個數組
var a = [1, 2, 2, '5', 4, 5, 6, 6, 8, 8, 2, 3, {name: 'object'}]
我們期望對它去重后的結果為
[1, 2, 3, 4, 5, 6, 8, '5', {name: 'object'}]

但上面的代碼得不到我們想要的結果

ES6引入了一種新的數據結構Set,它類似于數組诺舔,但是成員的值都是唯一的鳖昌,沒有重復的值。

另外低飒,兩個對象總是不相等的许昨。

上面代碼中,由于兩個空對象不相等褥赊,所以它們被視為兩個值糕档。但如果是對同一個對象的多次引用,則只被視為一個值拌喉。

Set 實例的屬性和方法

Set 結構的實例有以下屬性速那。

  • Set.prototype.constructor:構造函數俐银,默認就是Set函數。
  • Set.prototype.size:返回Set實例的成員總數端仰。

Set 實例的方法分為兩大類:操作方法(用于操作數據)和遍歷方法(用于遍歷成員)

  • 操作方法:
    • Set.prototype.add(value):添加某個值捶惜,返回Set結構本身。
    • Set.prototype.delete(value):刪除某個值荔烧,返回一個布爾值售躁,表示刪除是否成功。
    • Set.prototype.has(value):返回一個布爾值茴晋,表示該值是否為Set的成員。
    • Set.prototype.clear():清除所有成員回窘,沒有返回值诺擅。
  • 遍歷方法:
    • Set.prototype.keys():返回鍵名的遍歷器
    • Set.prototype.values():返回鍵值的遍歷器
    • Set.prototype.entries():返回鍵值對的遍歷器
    • Set.prototype.forEach():使用回調函數遍歷每個成員
s.add(1).add(2).add(2);
// 注意2被加入了兩次

s.size // 2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2) // false

我們可以使用Set來解決上面數組去重的問題

三、Map


JavaScript 的對象(Object)啡直,本質上是鍵值對的集合(Hash 結構)烁涌,但是傳統(tǒng)上只能用字符串當作鍵。這給它的使用帶來了很大的限制酒觅。

為了解決這個問題撮执,ES6 提供了 Map 數據結構。它類似于對象舷丹,也是鍵值對的集合抒钱,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵颜凯。

也就是說谋币,Object 結構提供了“字符串—值”的對應,Map 結構提供了“值—值”的對應症概,是一種更完善的 Hash 結構實現蕾额。

上面的例子展示了如何向 Map 添加成員。作為構造函數彼城,Map 也可以接受一個數組作為參數诅蝶。該數組的成員是一個個表示鍵值對的數組。

Map的遍歷方法

Map 結構原生提供三個遍歷器生成函數和一個遍歷方法募壕。

  • Map.prototype.keys():返回鍵名的遍歷器调炬。
  • Map.prototype.values():返回鍵值的遍歷器。
  • Map.prototype.entries():返回所有成員的遍歷器司抱。
  • Map.prototype.forEach():遍歷 Map 的所有成員筐眷。

四、WeakSet


WeakSet 結構與 Set 類似习柠,也是不重復的值的集合匀谣。但是照棋,它與 Set 有兩個區(qū)別。

1. WeakSet 的成員只能是對象武翎,而不能是其他類型的值
2. WeakSet 中的對象都是弱引用

垃圾回收機制不考慮 WeakSet 對該對象的引用烈炭,也就是說,如果其他對象都不再引用該對象宝恶,那么垃圾回收機制會自動回收該對象所占用的內存符隙,不考慮該對象還存在于 WeakSet 之中

這里無法通過代碼來檢測內存是否被GC,因為JS沒有暴露GC相關的API

上面的代碼中垫毙,當我們把對象a置為null之后霹疫,通常的理解是此時還有一個WeakSet引用著對象a,因此a所指向的內存不會被標記為垃圾综芥,從而不會被回收丽蝎。

但事實上,前面說過WeakSet是弱引用膀藐,當把a置為null之后屠阻,可以理解為此時WeakSet對a所指向的內存的引用就消失了,因此會正常的進行垃圾回收额各。

五国觉、WeakMap


WeakMap結構與Map結構類似,也是用于生成鍵值對的集合虾啦。WeakMapMap的區(qū)別有兩點麻诀。

1. WeakMap只接受對象作為鍵名(null除外),不接受其他類型的值作為鍵名
2. WeakMap的鍵名所指向的對象缸逃,不計入垃圾回收機制

WeakMap的設計目的在于针饥,有時我們想在某個對象上面存放一些數據,但是這會形成對于這個對象的引用需频。

const e1 = document.getElementById('foo');
const e2 = document.getElementById('bar');
const arr = [
  [e1, 'foo 元素'],
  [e2, 'bar 元素'],
];

上面代碼中丁眼,e1e2是兩個對象,我們通過arr數組對這兩個對象添加一些文字說明昭殉。這就形成了arre1e2的引用苞七。

一旦不再需要這兩個對象,我們就必須手動刪除這個引用挪丢,否則垃圾回收機制就不會釋放e1e2占用的內存蹂风。

// 不需要 e1 和 e2 的時候
// 必須手動刪除引用
arr [0] = null;
arr [1] = null;

上面這樣的寫法顯然很不方便。一旦忘了寫乾蓬,就會造成內存泄露惠啄。

WeakMap就是為了解決這個問題而誕生的,它的鍵名所引用的對象都是弱引用,即垃圾回收機制不將該引用考慮在內撵渡。因此融柬,只要所引用的對象的其他引用都被清除,垃圾回收機制就會釋放該對象所占用的內存趋距。也就是說粒氧,一旦不再需要,WeakMap里面的鍵名對象和所對應的鍵值對會自動消失节腐,不用手動刪除引用外盯。

基本上,如果你要往對象上添加數據翼雀,又不想干擾垃圾回收機制饱苟,就可以使用WeakMap。一個典型應用場景是狼渊,在網頁的 DOM 元素上添加數據掷空,就可以使用WeakMap結構。當該 DOM 元素被清除囤锉,其所對應的WeakMap記錄就會自動被移除。

const wm = new WeakMap();

const element = document.getElementById('example');

wm.set(element, 'some information');
wm.get(element) // "some information"

上面代碼中护锤,先新建一個WeakMap實例官地。然后,將一個 DOM 節(jié)點作為鍵名存入該實例烙懦,并將一些附加信息作為鍵值驱入,一起存放在WeakMap里面。這時氯析,WeakMap里面對element的引用就是弱引用亏较,不會被計入垃圾回收機制。

總之掩缓,WeakMap的專用場合就是雪情,它的鍵所對應的對象挠轴,可能會在將來消失践瓷。WeakMap結構有助于防止內存泄漏瘪贱。

以上只是對WeakMap的簡單介紹蒸甜,如果你想深入學習WeakMap請看這篇文章ES2015 WeakMap的學習和使用
如果想了解內存泄漏請看文章JavaScript 內存泄漏教程

參考:
Symbol MDN
阮一峰 ES6入門 Symbol
阮一峰 ES6入門 Set 和 Map 數據結構

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末倒慧,一起剝皮案震驚了整個濱河市饶碘,隨后出現的幾起案子稍刀,更是在濱河造成了極大的恐慌恬口,老刑警劉巖表悬,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弥锄,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機籽暇,發(fā)現死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門温治,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人图仓,你說我怎么就攤上這事罐盔。” “怎么了救崔?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵惶看,是天一觀的道長。 經常有香客問我六孵,道長纬黎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任劫窒,我火速辦了婚禮本今,結果婚禮上,老公的妹妹穿的比我還像新娘主巍。我一直安慰自己冠息,他們只是感情好,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布孕索。 她就那樣靜靜地躺著逛艰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搞旭。 梳的紋絲不亂的頭發(fā)上散怖,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音肄渗,去河邊找鬼镇眷。 笑死,一個胖子當著我的面吹牛翎嫡,可吹牛的內容都是我干的欠动。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼惑申,長吁一口氣:“原來是場噩夢啊……” “哼翁垂!你這毒婦竟也來了?” 一聲冷哼從身側響起硝桩,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤沿猜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碗脊,有當地人在樹林里發(fā)現了一具尸體啼肩,經...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡橄妆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了祈坠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片害碾。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赦拘,靈堂內的尸體忽然破棺而出慌随,到底是詐尸還是另有隱情,我是刑警寧澤躺同,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布阁猜,位于F島的核電站,受9級特大地震影響蹋艺,放射性物質發(fā)生泄漏剃袍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一捎谨、第九天 我趴在偏房一處隱蔽的房頂上張望民效。 院中可真熱鬧,春花似錦涛救、人聲如沸畏邢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棵红。三九已至,卻和暖如春咧栗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虱肄。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工致板, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人咏窿。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓斟或,卻偏偏與公主長得像,于是被迫代替她去往敵國和親集嵌。 傳聞我的和親對象是個殘疾皇子萝挤,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348