ECMA Script 6_唯一容器 Set_映射容器 Map

摘要:
setB.has)];//查找两个数组的差异集constdifArr=[…newSet(arrA.filter(each=>!');}}}映射对象。属性键可以是任何类型的属性键,并且是唯一的。上一个属性将由以下属性覆盖。传统上,对象只能使用字符串作为键ES6来提供映射数据结构。如果需要“键值对”数据结构,Map比Object更适合。varnewMap=newMap();不仅是数组,任何具有迭代器接口的数据结构以及每个成员都是一个双元素数组,都可以用作Map构造函数的参数Set和Map来生成新的Map。Map结构只能将对同一对象的引用视为同一关键字。

唯一容器 Set

ES6 提供了新的数据结构 Set

Set 结构没有键名,只有键值(或者说 键名 和 键值 是同一个值

它类似于数组,但是成员的值都是唯一的,没有重复的值

Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality” NaN 等于自身

它类似于精确相等运算符(===),而 精确相等运算符 认为NaN不等于自身

Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的 values 方法

Set.prototype[Symbol.iterator] === Set.prototype.values    // true

// 意味着 :  可以省略values方法,直接用for...of循环遍历 Set

  • 数组去重(面试题)
  • let arr = [9, 3, 1, 5, 7];
    
    let onlyOne = [...new Set(arr)];

    const oneArr = Array.from(new Set(arr));// Array.from方法可以将 Set 结构转为数组
  • Set.prototype.size        返回 Set 实例 的成员总数
  • Set.prototype.操作方法

setObj.add()

添加某个值,返回 Set 结构本身

setObj.delete()

删除某个值,返回一个布尔值,表示删除是否成功

setObj.has()

返回一个布尔值,表示该值是否为 Set 的成员

setObj.clear()

清除所有成员,没有返回值

  • // 对象的写法
    const properties = {
        'width': 1,
        'height': 1
    };
    
    if (properties[someName]) {
        // do something
    }
    
    // Set的写法
    const properties = new Set();
    
    properties.add('width');
    properties.add('height');
    
    if (properties.has(someName)) {
        // do something
    }
  • Set.prototype.遍历方法

setObj.keys()

返回键名遍历器

setObj.values()

返回键值遍历器

setObj.entries()

返回键值对遍历器

setObj.forEach()

使用回调函数遍历每个成员

还可以有第二个参数,表示绑定处理函数内部的 this 对象

  • let set = new Set(['red', 'green', 'blue']);
    
    for (let item of set.keys()) {
        console.log(item);
    };
    // red
    // green
    // blue
    
    for (let item of set.values()) {
       console.log(item);
    };
    // red
    // green
    // blue
    
    for (let item of set.entries()) {
        console.log(item);
    };
    // ["red", "red"]
    // ["green", "green"]
    // ["blue", "blue"]

Set 可以很容易地实现

并集(Union)

  • const unionArr = [...new Set([...arrA, ...arrB])];    // 求俩数组 并集

交集(Intersect)

  • const difArr = [...new Set(arrA.filter(each=>!setB.has(each)))];    // 求俩数组 差集

差集(Difference)

  • const difArr = [...new Set(arrA.filter(each=>!setB.has(each)))];    // 求俩数组 差集
  • let setA = new Set(arrA);    // arrA 去重
    let setB = new Set(arrB);    // arrB 去重
    
    const unionArr = [...new Set([...arrA, ...arrB])];    // 求俩数组 并集
    const mixedArr = [...new Set(arrA.filter(each=>setB.has(each)))];    // 求俩数组 交集
    const difArr = [...new Set(arrA.filter(each=>!setB.has(each)))];    // 求俩数组 差集
    
    console.log("
    
    arrA 去重      :  "+[...setA]);
    console.log("arrB 去重      :  "+[...setB]);
    console.log("------------------");
    console.log("arrA 并集 arrB :  "+unionArr);
    console.log("arrA 交集 arrB :  "+mixedArr);
    console.log("arrA 差集 arrB :  "+difArr);

var ws = mew WeakSet()

 

与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别: 

  • 首先,WeakSet 的成员只能是对象,而不能是其他类型的值
  • WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用

也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中

WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历机制无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了

  • WeakSet.prototype.add(value)

向 WeakSet 实例添加一个新成员

  • WeakSet.prototype.delete(value)

清除 WeakSet 实例的指定成员

  • WeakSet.prototype.has(value)

返回一个布尔值,表示某个值是否在 WeakSet 实例之中

  • const elements = new WeakSet();
    class Foo {
        constructor() {
            elements.add(this)
        }
        method () {
            if (!elements.has(this)) {
                throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
            }
        }
    }

Map 对象,属性 key 可以是任意类型

属性 key  也是唯一的,前面的属性 会被 后面的属性 覆盖

背景:

传统上对象只能用字符串当作

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,

各种类型的值(包括对象)都可以当作键。

也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

如果你需要 “键值对” 的数据结构,Map 比 Object 更合适。

  • ECMA Script 6_唯一容器 Set_映射容器 Map第1张

var newMap = new Map();

不仅仅是数组,任何具有 Iterator 接口、且每个成员都是 一个双元素的数组的数据结构 都可以当作Map构造函数的参数

SetMap 都可以用来生成新的 Map

只有对同一个对象的引用,Map 结构才将其视为同一个键。这一点要非常小心

  • const map = new Map();
    
    const k1 = ['a'];
    const k2 = ['a'];
    
    map
        .set(k1, 111)
        .set(k2, 222);
    
    map.get(k1);    // 111
    map.get(k2);    // 222

newMap.size 属性

返回 Map 结构的成员总数

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

newMap.set(key, value)    添加 键值对

设置键名 key 对应的键值为 value,然后返回整个 Map 结构,意味着可以链式调用

如果 key 已经有值,则键值会被更新,否则就新生成该键

  • const m = new Map();
    
    m.set('edition', 6)        // 键是字符串
    m.set(262, 'standard')     // 键是数值
    m.set(undefined, 'nah')    // 键是 undefined
    
    
    let map = new Map()
                                  .set(1, 'a')
                                  .set(2, 'b')
                                  .set(3, 'c');

newMap.get(key)    获取 键 对应的 值

读取 key 对应的键值

如果找不到 key,返回 undefined

  • const m = new Map();
    
    const hello = function() {console.log('hello');};
    m.set(hello, 'Hello ES6!');    // 键是函数
    
    m.get(hello);    // Hello ES6!

newMap.has(key)    查询 Map 实例 是否包含 键

返回一个布尔值,表示某个键是否在当前 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

newMap.delete(key)

删除 Map 实例的 某个键,返回 true。

如果删除失败,返回 false

newMap.clear()

清除所有成员,没有返回值

四种 遍历方法

  • keys()        返回键名的遍历器
  • values()        返回键值的遍历器
  • entries()        返回所有成员的遍历器
  • forEach()        遍历 Map 的所有成员

forEach方法还可以接受第二个参数,用来绑定this

  • const map = new Map([
        ['F', 'no'],
        ['T',  'yes'],
    ]);
    
    for (let key of map.keys()) {
        console.log(key);
    };
    // "F"
    // "T"
    
    for (let value of map.values()) {
        console.log(value);
    };
    // "no"
    // "yes"
    
    for (let item of map.entries()) {
        console.log(item[0], item[1]);
    };
    // "F" "no"
    // "T" "yes"
    
    // 或者
    for (let [key, value] of map.entries()) {
       ; console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    // 等同于使用map.entries()for (let [key, value] of map) {
        console.log(key, value);
    };
    // "F" "no"
    // "T" "yes"
    // 表示 Map 结构的默认遍历器接口(Symbol.iterator 属性),就是 entries 方法
    map[Symbol.iterator] === map.entries // true
  • Map 结构转为数组结构,比较快速的方法是使用扩展运算符(...)
  • const map = new Map([
        [1, 'one'],
        [2, 'two'],
        [3, 'three'],
    ]);
    
    [...map.keys()]    // [1, 2, 3]
    
    [...map.values()]    // ['one', 'two', 'three']
    
    [...map.entries()]    // [[1,'one'], [2, 'two'], [3, 'three']]
    
    [...map]    // [[1,'one'], [2, 'two'], [3, 'three']]

 

返回键名的遍历器

免责声明:文章转载自《ECMA Script 6_唯一容器 Set_映射容器 Map》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Firemonkey的几个特色属性(一)javascript 设置cookie(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

全面聊聊JavaScript的浅拷贝和深拷贝

一、背景      首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = obj copyobj .name = '设计...

11 libubox

1 libubox 主要提供事件循环,二进制块格式处理、linux链表实现和一些JSON辅助主要包含3个软件包:libubox、jshn、libblobmsg-json 1.1 libubox 1、提供多种基础通用功能接口。如:链表、平衡二叉树、二进制块处理、MD5等2、提供多种sock接口封装3、提供事件驱动机制及任务管理功能 utils.h...

JS 三维数组赋值

 一维数组:[1,2,3];  //数组的每一个元素是一个标量 二维数组:[["a","b","c"],[1,2,3],123];  //数组的每一个元素是一个一维数组 三维数组:[[["a","b","c"],[1,2,3]],[["a","b","c"],[1,2,3]]];  //数组的每一个元素是一个二维数组 需要注意的是,多维空数组不能直接向某个...

MVVM大比拼之avalon.js源码精析

简介 avalon是国内 司徒正美 写的MVVM框架,相比同类框架它的特点是: 使用 observe 模式,性能高。 将原始对象用object.defineProperty重写,不需要用户像用knockout时那样显示定义各种属性。 对低版本的IE使用了VBScript来兼容,一直兼容到IE6。 需要看基础介绍的话建议直接看司徒的博客。在网上搜...

javascript 中数组的创建 添加 与将数组转换成字符串 页面三种提交请求的方式

创建js数组 var array=new Array(); Java中创建数组 private String[] array=new String[3]; 两个完全不同的,js中是可变长度的 添加内容 array.push(something); java中 array[0]="abc"; 数组转字符串 array.join(",") java中 St...

Java 集合系列17之 TreeSet详细介绍(源码解析)和使用示例

概要 这一章,我们对TreeSet进行学习。我们先对TreeSet有个整体认识,然后再学习它的源码,最后再通过实例来学会使用TreeSet。内容包括:第1部分 TreeSet介绍第2部分 TreeSet数据结构第3部分 TreeSet源码解析(基于JDK1.6.0_45)第4部分 TreeSet遍历方式第5部分 TreeSet示例 转载请注明出处:http...