ES6之新的数据结构

新的数据结构

  目录:

  • 新的数据结构
    • 无序集合 Set
      • 数组与集合的区别
      • 增减元素
      • 检查元素
      • 遍历元素
        • forEach
        • for-of
    • WeakSet
    • Map映射类型
    • WeakMap


无序集合 Set

数组与集合的区别

   数组 集合
元素序列 有序 无序
元素可重复性 元素可重复 元素不可重复



  用法:new Set([iterable]) : Set

const set = new Set();
const set = new Set([1, 2, 3]);


增减元素

  通过 adddeleteclear 方法来添加删除清空集合内的元素。

const set = new Set();

// 添加元素
set
    .add(1)
    .add(2)
    .add(3)
    .add(3);  // 这一句并不会起到任何作用,因为元素3已存在
console.log(set);   // Set(3) {1, 2, 3}

// 删除元素
set.delete(2);
console.log(set);   // Set(2) {1, 3}

// 清空集合
set.clear();
console.log(set);   // Set(0) {}


检查元素

  因为集合并没有排序的概念,所以集合对象并没有像数组对象那样有 indexOf 方法,也就意味着不能通过 set.indexOf(value) >= 0 的形式来检查元素是否存在于集合中。但集合对象提供了 has 方法用于检查某集合中是否包含某一个元素

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

//检查元素
set.has(2);  // true
set.has(5);  // false


遍历元素

forEach

  集合对象的 forEach 方法和数组类型的一样,传入一个回调函数以接受集合内的元素,并且可以为这个回调函数指定一个上下文,同样的,集合对象的 forEach 方法也是无法被中断的。

setObj.forEach(callbackfn[, thisArg])


  • setObj: 必需。Set 对象。
  • callbackfn: 必需。callbackfn 最多接受三个参数。对于集合中的每个元素,forEach 都会调用函数一次。
  • thisArg:可选。可在 callbackfn 函数中为其引用 this 关键字的对象。如果省略 thisArg,则 undefined 将用作 this 值。

注意无法为箭头函数指定一个上下文

function callbackfn(value, key, setObj)
回调参数 定义
Value 集中包含的值
key 集中包含的值。一组没有键,因此此值与 value 相同
setObj 要遍历的 Set 对象
const set = new Set([1, 2, 3, 4]);

set.forEach(item => {
    console.log(item);
});
// 1
// 2
// 3
// 4

set.forEach(function(item){
    console.log(item * this.foo);
}, {foo: 2});
// 2
// 4
// 6
// 8


for-of

  for-of 循环语句可以迭代可迭代对象(Iterable Object),并可以配合 const 和 let 使用,从而解决 forEach 方法不可中断的问题。

const set = new Set([1, 2, 3, 4]);
for(const val of set){
    console.log(val);
} 
// 1 2 3

WeakSet

const weakset = new WeakSet();
weakset.add(1); // Uncaught TypeError: Invalid value used in weak set

weakset.add({foo: 1});
console.log(weakset);   // WeakSet {}

console.log(weakset.size);  // undefined

  WeakSet 与 Set 不同的地方:

  1. WeakSet 不能包含值类型元素,否则会抛出一个 TypeError。
  2. WeakSet 不能包含无引用的对象,否则会自动清除出集合。
  3. WeakSet 无法被探知其大小,也无法被探知其中所包含的元素。
const weakset = new WeakSet();
let foo = {bar: 1};

weakset.add(foo);
console.log(weakset.has(foo));  // true

foo = null;
console.log(weakset.has(foo));  // false



  实现将字符串等值类型加入到 WeakSet 数据结构中:

var ws = new WeakSet();

var str = new String("Hello");
var num = new Number(1);

ws.add(str);
ws.add(num);

console.log(ws.has(str));  // true
console.log(ws.has(num));  // true

  这种做法的弊端在于,被加入到 WeakSet 中的字符串和数字等不能被修改,因为一旦进行修改其引用便会丢失,甚至导致被移除出集合。

str += "hehe";
console.log(ws.has(str));   // false

WeakSet 最大的实用意义在于,可以让我们直接对引擎中垃圾收集器的运行情况有程序化的探知方式,开发者可以利用 WeakSet 的特性以更高的定制化方案来优化程序的内存使用方案。


Map映射类型

  用法:new Map([iterable]) : Map

const map  = new Map();

  在创建映射对象时,可以将一个以二元数组(键值对)作为元素的数组传入到构建函数中,其中每一个键值对都会加入到该映射对象中。该数组内的元素会以数组顺序进行处理,如果存在相同的键,则会按照先进先出(FIFO)原则,以该键最后一个处理的对应值为最终值。

const map = new Map([['foo', 1], ['foo', 2]]);
console.log(map.get('foo'));    // 2



映射对象操作方法

操作方法 方法内容
set(key, value) 添加键值对到映射中
get(key) 获取映射中某一个键的对应值
delete(key) 将某一键值对移除出映射中
clear() 清空映射中所有的键值对
entries() 返回一个以二元数组(键值对)作为元素的数组
has(key) 检查映射中是否包含某一键值对
keys() 返回一个一当前映射中所有键作为元素的可迭代对象
values() 返回一个一当前映射中所有值作为元素的可迭代对象
map.size 映射中键值对的数量



映射对象和 Object 的区别

   映射对象 Map 普通对象 Object
存储键值对
对遍历所有键值
检查是否包含指定键值对
使用字符串(String)作为键
使用 Symbol 作为键
使用任意对象作为键
可以方便地得知键值对的数量



  除了语法和实现层面上的区别之外,映射对象和普通对象的区别还体现在 JSON 的序列化结果中。Object 的 JSON 序列化结果是标准的对象字面量形式,而 Map 的 JSON 序列化结果是以关联数组的形式表达。

const map = new Map();
map.set('foo', 1);
map.set('bar', 2);

const str = JSON.stringify(map);
console.log(str);   // [["foo",1],["bar",2]]

// ...data transport
const otherMap = new Map(JSON.parse(str));
console.log(otherMap.get('bar'));  // 2

WeakMap

  和 WeakSet 类似,只不过 WeakMap 的键会检查变量引用,只要其中一个引用全被解除,该键值对就会被删除。

const weakmap = new WeakMap();
let keyObject = {id: 1};
const valObject = {score: 100};

weakmap.set(keyObject, valObject);
weakmap.get(keyObject);  // {score: 100}
keyObject = null;
console.log(weakmap.has(keyObject));  // false

你可能感兴趣的:(ES6)