浅谈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]

如有错误,欢迎大家指出,感激不尽~~~

发布了76 篇原创文章 · 获赞 320 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_42881768/article/details/104941837