淺談JavaScript中ES6新增的Set和Map結構以及Array.from方法

1、Set

  • ES6 提供了新的數據結構 Set。它類似於數組,但是成員的值都是唯一的,沒有重複的值。
  • Set 本身是一個構造函數,用來生成 Set 數據結構。
  • 只能接受數組,採用new的方式來實例化使用。
  • 創建Set機構時,可以立即設置內容,Set必須接受數組作爲參數。
  • 常用的屬性和方法有:

size 屬性: 獲取該數據結構中,數據的數據個數
add() 方法: 向該數據結構中,追加新增數據
constructor:構造函數,默認就是Set函數
delete() 方法: 向該數據結構中,刪除指定的數據
clear() 方法: 清除該數據結構中,所有的數據
has() 方法: 查詢數據結構中,有沒有某個數據
forEach() 方法: 用來遍歷Set數據結構

注意:Set數據的獲取需要藉助展開運算符(...),並放在數組中才能夠解析

例 1:
下面的代碼通過add方法向 Set 結構加入成員,結果表明 Set 結構不會添加重複的值。

const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));

for (let i of s) {
  console.log(i);}    // 2 3 5 4

例 2 :
擴展運算符和 Set 結構相結合,就可以去除數組的重複成員。

let arr = [1, 2, 3, 3, 2, 1];
let unique = [...new Set(arr)];
// [1, 2, 3]

所以,我們可以利用Set的這個屬性做一個簡單的數組去重的封裝。

function norepeat(arr){
    var s = new Set(arr);
    return [...s];
}
var a = norepeat([4,5,6,7,8,6,5,4,3,2,1]);
console.log(a);  // [4, 5, 6, 7, 8, 3, 2, 1]

例 3:
Set 函數可以接受一個數組(獲取dom的nodelist對象)作爲參數,用來初始化,同時也運用了數組去重的特性。

const set = new Set([1, 2, 3, 4, 4]);[...set]
// [1, 2, 3, 4]
// ---------------------------------------------------

const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5
// ---------------------------------------------------

const set = new Set(document.querySelectorAll('div'));
set.size // 打印出div的數目

例 4:
向 Set 加入值的時候,不會發生類型轉換,所以1和"1"是兩個不同的值。Set 內部判斷兩個值是否不同,使用的算法叫做“Same-value-zero equality”,它類似於精確相等運算符(===),主要的區別是NaN等於自身,而精確相等運算符認爲NaN不等於自身。

let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
function norepeat(arr){
    var s = new Set(arr);
    return [...s];
}
var a = norepeat([4,5,6,7,8,"7",6,5,4,3,2,1]);
console.log(a);  // [4, 5, 6, 7, 8, "7", 3, 2, 1]

例 5:
同時我們還知道,Array.from方法可以將 Set 結構轉爲數組。(Array.from方法在下面也有介紹)

const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

例 6:
Set 結構的實例默認可遍歷。

let set = new Set(['red', 'green', 'blue']);

for (let a of set) {
  console.log(a);}
// red
// green
// blue

例 7:
Set 結構的實例與數組一樣,也擁有forEach方法,用於對每個成員執行某種操作,沒有返回值。但是,Set的forEach方法的參數就是一個處理函數。該函數的參數與數組的forEach一致,依次爲鍵值、鍵名、集合本身(上例省略了該參數)。這裏需要注意,Set 結構的鍵名就是鍵值(兩者是同一個值),因此第一個參數與第二個參數的值永遠都是一樣的。

set = new Set([6, 8, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 6 : 6
// 8 : 8
// 9 : 9

2、Map

  • JavaScript 的對象(Object),本質上是鍵值對的集合(Hash結構),但是傳統上只能用字符串當作鍵。這給它的使用帶來了很大的限制
  • ES6 提供了 Map數據結構。它類似於對象,也是鍵值對的集合但是“鍵”的範圍不限於字符串,各種類型的值(包括對象)可以當作鍵。
  • 也就是說,Object 結構提供了“字符串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash結構實現。如果你需要“鍵值對”的數據結構,Map 比 Object 更合適。
  • 也可以這麼理解:Map只能接受數組,而且是二維數組,而且第二維數組只能有兩個數據,如果有多個,則不解析。
  • 如果第二維數組的第一個數據被解析成了key,第二維數組的第二個數據被就解析成了value.

Map 結構的實例有以下屬性和操作方法:

size 屬性:獲取該數據結構中,數據的數據個數
set() 方法:向該數據結構中,新增數據
get() 方法:向該數據結構中,獲取數據
delete() 方法:向該數據結構中,刪除指定的數據
clear() 方法:清除該數據結構中,所有的數據
has() 方法:查詢數據結構中,有沒有某個數據
forEach() 方法:用來遍歷Map數據結構

(1)size 屬性
size屬性返回 Map 結構的成員總數。

const map = new Map();
map.set('foo', true);
map.set('bar', false);

map.size // 2

(2)set(key, value)
set方法設置鍵名key對應的鍵值爲value,然後返回整個 Map 結構。如果key已經有值,則鍵值會被更新,否則就新生成該鍵。

const m = new Map();

m.set('edition', 6)      // 鍵是字符串
m.set(262, 'standard')    // 鍵是數值
m.set(undefined, 'nah')  // 鍵是 undefined

set方法返回的是當前的Map對象,因此可以採用鏈式寫法

let map = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');

(3)get(key)
get方法讀取key對應的鍵值,如果找不到key,返回undefined。

const m = new Map();

const hello = function() {console.log('hello');};
m.set(hello, 'Hello ES6!') // 鍵是函數

m.get(hello) // Hello ES6!

(4)has(key)
has方法返回一個布爾值,表示某個鍵是否在當前 Map 對象之中。

const m = new Map();

m.set('edition', 6);
m.set(262, 'standard');
m.set(undefined, 'nah');

m.has('edition')    // true
m.has('years')      // false
m.has(262)          // true
m.has(undefined)    // true

(5)delete(key)
delete方法刪除某個鍵,返回true。如果刪除失敗,返回false。

const m = new Map();
m.set(undefined, 'nah');
m.has(undefined)    // true

m.delete(undefined)
m.has(undefined)      // false

(6)clear()
clear方法清除所有成員,沒有返回值。

let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
map.clear()
map.size // 0

遍歷map: 需要特別注意的是,Map 的遍歷順序就是插入順序,如下代碼所示:

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],]);
  for (let [key, value] of map) {
  console.log(key, value);}
// "F" "no"
// "T" "yes"

3、Array.from

Array.from方法用於將兩類對象轉爲真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象(ES6 新增的數據結構 Set 和Map)。

(1)咱們來舉個例子 ~~~ 下面是一個類似數組的對象,看Array.from將它轉爲真正的數組:

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3};

let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

注意: 在我們的實際應用中,常見的類似數組的對象是 DOM 操作返回的 NodeList 集合,以及函數內部的arguments對象。Array.from都可以將它們轉爲真正的數組。

(2)ES6 允許直接寫入變量和函數,作爲對象的屬性和方法。因爲這樣的書寫更加簡潔,可以看下面的代碼:

const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
    // 等同於 如下:
const baz = {foo: foo};

(3)除了屬性簡寫,方法也可以簡寫,如下代碼:

const o = {
  method() {
    return "Hello!";
  }
};
// 等同於
const o = {
  method: function() {
    return "Hello!";
  }
};

(4)在 Array.from 中使用箭頭函數:

Array.from([1, 2, 3], x => x + x);
// [2, 4, 6]

// -----------------------------------

Array.from({length: 5}, (v, i) => i);
// [0, 1, 2, 3, 4]

如有錯誤,歡迎大家指出,感激不盡~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章