唯一容器 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("\n\narrA 去重 : "+[...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 更合适。

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); //
    map.get(k2); //

newMap.size 属性

返回 Map 结构的成员总数

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

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的更多相关文章

  1. ECMA Script 6_异步编程之 Promise

    Promise 对象 异步编程 方案,已同步的方式表达异步的代码,解决回调地狱的问题 比传统的解决方案——回调函数和事件——更合理和更强大 是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步 ...

  2. ECMA Script 6_模块加载方案 ES6 Module 模块语法_import_export

    1. 模块加载方案 commonJS 背景: 历史上,JavaScript 一直没有模块(module)体系, 无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来. 其他语言都有这项功能: ...

  3. ECMA Script 6_简单介绍

    ECMAScript 6 ECMA 组织 前身是 欧洲计算机制造商协会 指定和发布脚本语言规范,标准在每年的 6 月份正式发布一次,作为当年的正式版本 这样一来,就不需要以前的版本号了,只要用年份标记 ...

  4. ECMA Script 6_数值的扩展

    1. 二进制 和 八进制 新的表示法 前缀 0b(或0B) 表示 二进制 前缀 0o(或 0O )表示 八进制 console.log(0b111110111 === 503); // true co ...

  5. ECMA Script 6_数组的扩展_扩展运算符

    1. 扩展运算符 内部调用的是数据结构的 Iterator 接口, 因此只要具有 Iterator 接口的对象,都可以使用扩展运算符 ... 如 map,,,, [...arr] 扩展运算符(spre ...

  6. ECMA Script 6_必须要知道的基础

    ES6 为了保持兼容性,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性: 另一方面规定,let 命令.const 命令.class 命令声明的全局变量,不属于 window ...

  7. ECMA Script 6_解构赋值_模式匹配

    解构赋值 从数组中提取值,按照对应位置,对变量赋值 只要等号右边的值不是对象或数组,就先将其转为对象. 由于 undefined 和 null 无法转为对象,所以对它们进行解构赋值,都会报错 let ...

  8. ECMA Script 6_字符串_扩展_字符 是4字节还是2字节?_模板字符串

    ES6 字符串扩展 ES6 加强了对 Unicode 的支持,并且扩展了字符串对象 字符 的 Unicode 表示法 允许采用 \uxxxx 形式表示一个字符, 其中 xxxx 表示字符的 Unico ...

  9. ECMA Script 6_函数的扩展

    ES6规定只要函数参数使用了默认值.解构赋值.或者扩展运算符, 那么函数内部就不能显式设定为严格模式,否则会报错 1. 参数的默认值 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面 函数 ...

随机推荐

  1. Consequence of Point-by-Point Bounds

    设 $X$ 是完备距离空间, $\scrF$ 是 $X$ 上的实连续函数族且具有性质: 对于每一 $x\in X$, 存在常数 $M_x>0$, 使得对于每一 $F\in\scrF$, $$\b ...

  2. python中的转义字符

    当我们需要在字符中添加特殊符号时,我们需要用\(即反斜杠来转义字符) 常用的转义字符: 注:如果不想转义添加的特殊字符,需要显示字符串原来的意思的时候,需要用r或R来定义 结果是这样的

  3. 第二章 Android系统与嵌入式开发

    第二章 Android系统与嵌入式开发 第二章首先要先了解Android和嵌入式Lnux系统有什么区别和联系,嵌入式Linux系统是在嵌入式设备中运行Linux系统:Android系统是在嵌入式设备中 ...

  4. Centos7 安装 tree

    Centos7 安装 tree 用命令 yum 安装  tree yum -y install tree

  5. Emmet(以前的Zencoding)的使用

    Emmet就是以前的Zencoding div.wrapper#wrapper>div.right+div.left*2>span{nimei$}*3 //. 类名 #id >下面 ...

  6. .Net三层架构

    .Net三层架构   希望朋友们留下自己对三层架构的理解... 三层体系结构的概念 用户界面表示层(USL) 业务逻辑层(BLL) 数据访问层(DAL) BLL将USL与DAL隔开了,并且加入了业务规 ...

  7. 帆软报表(finereport)图表——扇形图/等弧度的玫瑰图

    扇形图/等弧度的玫瑰图,展示的是展示数据所占的比例,需要所有数据的和加起来为1. 下面利用一个实例说明玫瑰图的用法和设置起始角度和终止角度,操作如下: 1.配置一个内置数据集 新增一个等弧度的玫瑰图模 ...

  8. 帆软报表(finereport)安装/配置

    1.首先是安装帆软报表软件 下载地址:http://www.finereport.com/product/download           激活码注册格账号就有了 2.启动软件,新建连接数据库 点 ...

  9. Task.Run与Task.Factory.StartNew的区别

    Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ...

  10. 【原创】大数据基础之Kudu(1)简介、安装、使用

    kudu 1.7 官方:https://kudu.apache.org/ 一 简介 kudu有很多概念,有分布式文件系统(HDFS),有一致性算法(Zookeeper),有Table(Hive Tab ...