Sets 和数组一样,都是一些有序值的的集合,但是Sets 和数组又有所不同,首先Sets 集合中不能存有相同的值,如果你向Sets 添加重复的值,它会忽略掉, 其次Sets 集合的作用也有所不同,它的主要作用一是存储数据,二是在于看一个值是不是在集合中,而不是对单个值进行操作,Sets 的查找更快。那怎样才能创建一个Sets, 使用new  Set(); 怎样才能添加值呢? 调用add() 方法

let set = new Set();
set.add();
set.add(); set.add({
name: 'sam'
})

  刚才我们说了,Sets 集合中不能添加重复的值,如果添加了,Sets 也会把它忽略掉,现在就可以试一试了,添加一个1,

let set = new Set();
set.add();
set.add(); set.add({
name: 'sam'
})
set.add()

  那我们怎么才能知道有没有添加到set中呢? 它又一个size属性,可以返回集合中又多少个元素,

console.log(set.size)  //

  set 中只要3个元素, 表明没有添加成功, 直接console.log(set), 也能看出它里面的包含的值。那这又引出了例外一个问题,Sets 集合是怎么判断两个值是重复或相等呢?内部调用的是Object.is() 方法判断相等性。

  除了调用add() 方法添加数据外,我们也可以创建Sets 的时候,直接进行初始化。new Set() 可接受数组作为参数,如果数组中有重复的值,初始化的时候直接过滤掉。

let set = new Set([, , , , ]);
console.log(set.size) //

  添加数据之后,能不能删除呢? 当然可以了,调用 delete() 方法可以删除一个元素,调用clear() 方法直接清空集合。

let set = new Set([, , , , ]);
console.log(set.size) // set.delete(); // 删除集合中的元素1
console.log(set.size); //
set.clear(); // 清空集合
console.log(set.size); //

  还有一个has 方法,就是判断一个元素是不是在集合中

let set = new Set([, , , , ]);
set.has(); // true
set.has(); // false

  刚才我们说了,可以使用console.log 来查看集合的内容,其实还有更好的办法,就是forEach 方法,对集合进行迭代。forEach 方法和数组的forEach 用法一致,都是接受一个函数,函数有三个参数,不过这三个参数和数组的不同,因为Sets 集合中并没有index, 对于Sets 集合的迭代来说,第一个是value, 第二个值也是value, 第三个是集合本身,你可能会问,第一个和第二个参数的值一致,为什么还要设置这个参数, 这是因为保持forEach API 的用法一致,如果Sets 的forEach 单独两个参数,那很容易忘掉。

let set = new Set([, , , , ]);
set.forEach(function(value, key, ownerSet) {
console.log(value, key);
console.log(value === key);
console.log(ownerSet === set)
})

  既然可以使用数组对Sets集合进行初始化,那么Sets集合能不能转化成数组呢?也可以,使用... 分割符。

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

  这时可以发现对数组进行了去重,简单的数组去重,用Sets 集合就可以解决了。

  以上我们创建的set 称为强set(Strong set), 为什么呢? 主要是因为当set 存储对象的时候,它存储的是对象的引用,只要set 存在,它里面引用的对象也会存在,对象就不会被垃圾回收,即使set 外面 这个对象的所有引用都消失了。

let set = new Set();
let obj = {}; set.add(obj);
console.log(set.size); // 1

  现在set 创建成功了, 并且存储了一个对象的引用obj. 那现在让对象的引用消失,obj =null; 你会发现set 中仍然存在着对象的引用,因为set.size 为1;

obj = null;
console.log(set.size); //

  我们可以把set 转化成数组,看到里面有一个对象

console.log([...set])

  但有时候,我们并不想这么做,尤其是操作dom的时候。如果set 集合中存储的是一个DOM 对象的引用,当我们把这个dom元素删除掉,这个元素的引用 其实就没有作用了,set 中再保留这个 dom 对象的引用也就没有意义了。 简单的dom结构

 <div id="app">
<button type="button" class="btn">5+6的结果</button>
</div>

  创建set实例,保存这个dom 的引用

let set = new Set();
let btn = document.getElementsByClassName('btn')[0];
set.add(btn);

  然后删除这个btn 元素

document.getElementById('app').removeChild(btn);

  这时候,你会发现页面中没有这个元素了,但是btn 和 set 集合中仍然保留这个btn 元素的引用。

console.log(btn);
console.log(set.size); // 1

  btn  好办,直接设置为null 就好了。但是set 中的元素就不好办了,这时ES6 提供了weak set, 专门处理这种引用的问题,如果 set  中引用的对象,就剩下在set 中的引用了,那么set 中的引用就会消失,对象也就可以垃圾回收了。

  创建weak set 使用的weakSet 函数,并且它里面只存对象,add, delete, has 方法和  set 使用一致,

let weakSet = new WeakSet();
let obj = {}; weakSet.add(obj);
weakSet.has(obj);
weakSet.delete(obj);

  和set 最大的不同就是我们上面刚说的,如果 obj = null, 就只剩下weakset 中存在对象的引用,那么这个引用也会消失,但是没有更好的判判断方法。

obj = null;

  执行obj = null; 后,我们就可以判断weakSet 中,没有对象的引用了。除了这个不同外, weakset, 不能迭代,没有size 和forEach 方法,它只能存储对象。

  Map

  Map和对象一样,都是键值对的方式存储数据,但是你想,有对象了,还要map 做什么? map 更强大,因为对象的所有key  都是字符串,你即使添加的时候不是字符串,对象也会 key 转化为字符串。

let obj = {};
let num = 5;
let string = '5'
obj[num] = '5 string';
obj[string] = '5 number';
console.log(obj); // {'5' : '5 number'}

    我们给对象添加了两个属性,一个是数字5, 一个是字符串‘5’, 但到最后发现对象中只有一个字符串5. 因为当我们给对象添加数字5的时候,它先转化为字符串‘5’, 发现对象中已经有字符串5 的属性了,就变成了改变对象的属性值了。 map 就不一样了,键和值可以是任意类型。创建map 使用的是new Map, 添加属性使用的是set 方法,set 也简单, 有俩个参数,第一个是key, 第二个是value.

let map = new Map();
map.set(5, '5 number');
map.set('5', '5 string');
console.log(map); // Map { 5 => '5 number', '5' => '5 string' }

  当我们向map 中增加key/value的时候,它是怎么判断这个key是不是存在map 中呢? 使用的是Object.is() 方法来进行判断,没有进行类型转化,所以 key 可以是任意值了。给map 添加值以后,怎么获取呢?使用get 方法,一个参数key

console.log(map.get(5)); // '5 number'

  除了这两个方法方法外,它还要has, delete, clear 方法,同时有一个 size  属性。 has 接受一个参数key, 判断存不存在,delete 接受一个参数key, 删除这个key, clear 不接受参数,直接清空map. size 以上返回有多少数据。

let map = new Map();
map.set(5, '5 number');
map.set('5', '5 string'); console.log(map.has(5)); // true
console.log(map.size); //
map.delete(5);
console.log(map.has(5)); // false
console.log(map.size); //
map.clear();
console.log(map.size) //

  Map 也可以使用数组进行初始化,不过,数组要用二维数组,因为map 中的每一项都是key/value,  数组中的每一项也应该有两个值,两个值只能用再用一个数组进行表示了,数组的第一项是key, 第二项是value。

let map = new Map([['name', 'json'], ['age', 30]]);

  你可想到key/value 不应该是对象吗,数组中的每一项是对象才对,但我们也说了,对象的key 只能是字符串,所以不能完全表示map,因为map 的key 是任意值,数组正好,数组中的每一项都是任意值,只不过语法比较奇怪, 数组的第一项是key, 第二项是value.

  获取到map 后,可以使用forEach 进行迭代,用法也会数组一致。

let map = new Map([['name', 'json'], ['age', 30]]);
map.forEach((value, key, ownerMap) => {
console.log(value, key);
console.log(map === ownerMap)
})

  和WeakSet 一样,map 也提供了WeakMap, WeakMap 的key 是必须是对象,如果 key引用的一个对象,只剩下在weakMap的key 中引用,其他的对这个对象的引用都不存在了,weakMap 中的key以及它对应的value就会自动删除。weak map 的创建是new WeakMap(); 它有set get, has, delete 方法,但没有size, clear(), forEach  等。

let map = new Map();
let btn = document.getElementsByClassName('btn')[0]; map.set(btn, 'btn');
map.get(btn);
map.has(btn);
map.delete(btn); btn = null; // map 中的key btn 以及它的value 会自动删除

  weak map  还要一个作用,可以创造对象的私有属性, 当我创建对象的时候,通常写一个构造函数

function Person(name) {
this. name = name;
} Person.prototype.getName = function() {
return this.name;
}

  但这时,创建一个Person 对象的时候,我们可以直接访问name 属性,

const person = new Person('sam');
console.log(person.name) // sam

  但是我们不想让用户直接访问name 属性, 直接使用下面的方法

let Person = (function(){
let privateData = new WeakMap(); function Person(name) {
privateData.set(this, {name: name})
}
Person.prototype.getName = function() {
return privateData.get(this).name;
} return Person;
})() let person = new Person('json');
console.log(person.getName()) // josn

ES6 新增集合----- Set 和Map的更多相关文章

  1. ES6——新增数据结构Set与Map的用法

    ES6 提供了新的数据结构 Set以及Map,下面我们来一一讲解. 一.Set 特性 似于数组,但它的一大特性就是所有元素都是唯一的,没有重复. 我们可以利用这一唯一特性进行数组的去重工作. 1.单一 ...

  2. ES6 新增数据类型检测 Set Map Proxy

    检测代码方法 function isNative(api){ return /native code/.test(api.toString())&&typeof api !== 'un ...

  3. ES6新增常见特性

    一:声明属性let const var let const 区别 1.var声明变量会发生变量提升,let.const不会发生变量提升 2.var允许重复声明变量,let不可以 3.const声明变量 ...

  4. 【读书笔记】【深入理解ES6】#7-Set集合和Map集合

    ES6新标准中将Set集合和Map集合添加到JS中. ES5中Set集合和Map集合 在ES5中,开发者们用对象属性来模拟这两种集合. var set = Object.create(null); s ...

  5. ES6新增的数据类型Map和Set。

    Javascript的默认对象表示方式 {} ,即一组键值对. 但是Javascript的对象有个小问题,就是键必须是字符串.但实际上Number或者其他数据类型作为键也是非常合理的. 为了解决这个问 ...

  6. ES6中的Set和Map集合

    前面的话 在ES6标准制定以前,由于可选的集合类型有限,数组使用的又是数值型索引,因而经常被用于创建队列和栈.如果需要使用非数值型索引,就会用非数组对象创建所需的数据结构,而这就是Set集合与Map集 ...

  7. ES6新增的常用数组方法(forEach,map,filter,every,some)

    ES6新增的常用数组方法 let arr = [1, 2, 3, 2, 1]; 一 forEach => 遍历数组 arr.forEach((v, i) => { console.log( ...

  8. ES6新增Map、Set和iterable

    Map需要一个二维数组 var test_map = new Map(["mians",99],["regink",88]) test_map.get(&quo ...

  9. ES6 - Note6:Set与Map

    Set和Map是ES6中新增的数据结构,Set是集合,无序唯一,Map类似于对象,也是"key-value"形式,但是key不局限于字符串. 1.Set的用法 Set是构造函数,可 ...

随机推荐

  1. 修改Jupyter Notebook默认文件存储路径(已安装Anaconda)

    https://blog.csdn.net/weixin_44799144/article/details/91823079 修改Jupyter Notebook默认文件存储路径首先,安装好Anaco ...

  2. 同一个交换机 局域网内 内网IP ping不通为什么 没关闭windows防火墙

    同一个交换机 局域网内 内网IP  ping不通为什么  没关闭windows防火墙

  3. 闭包(python)

    1.闭包的理解 我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包. 2. 闭包的格式 下面用伪代码进行闭包格式的描 ...

  4. ocketMQ概念模型

    ocketMQ概念模型 https://blog.csdn.net/binzhaomobile/article/details/73332463 HTTPS://blog.CSDN.net/bin找M ...

  5. SNF快速开发平台2019-权限管理模型-平台服务(多平台\多组织\SAAS\多系统)

    1.1    不同组织机构 通俗的讲,就是一个集团公司,划分几个区域,每个区域都有什么分公司,每个分公司都有哪些部门一样,哪些部门又有那些子部门等. 当然也可以是外贸公司的全球性客户.合作伙伴的分布情 ...

  6. win 程序开机自启动设置

    若程序设置了开机自启动,但是仍没有效果,可能是被什么拦截了,或者什么原因.导致开机并没有自启动,那么如何解决呢? 解决方法:将软件的快捷方式 或 单个软件 直接拷贝到 如下目录,即可强制实现开机自启动 ...

  7. react 核心技术点

    1.react生命周期 react生命周期分为初始化阶段.运行阶段.销毁阶段. (1) 初始化阶段: componentWillMount:实例挂载之前 Render:渲染组件 componentDi ...

  8. HDFS java API TROUBLESHOOTING

    官方文档:https://hadoop.apache.org/docs/r2.9.2/hadoop-project-dist/hadoop-common/SingleCluster.html 配置免密 ...

  9. UltraEdit 替换符

    1.在每行的最后一行添加字符串: 打开替换,在查找中输入 ^r  在替换栏中输入要替换的字符  再把下边的正则表达式勾选,然后开始或是全部替换就可以了 2.替换回车换行 在查找中输入 要替换的字符  ...

  10. Oracle Spatial分区应用研究之六:全局空间索引下按县分区与按省分区效率差异原因分析

    1.实验结论 全局空间索引下,不同分区粒度之所有效率会有不同,差异并不在于SDO_FILTER操作本身,而在于对于数据字典表的访问次数上: 分区越多.表上的lob column越多,对数据字典表的访问 ...