对象、Map、Set、WeakMap、WeakSet

本文写于 2020 年 11 月 24 日

总的来说,Set 和 Map 主要的应用场景分别在于数据重组数据储存。Set 是一种叫做「集合」的数据结构,Map 是一种叫做「字典」的数据结构。

太长不看版本

Set

  1. 成员不能重复;
  2. 只有键值,没有健名,有点类似数组;
  3. 可以被遍历,方法有 add, delete, has

WeakSet

  1. 成员都是对象;
  2. 成员都是弱引用,随时可以消失,因此可以用来保存 DOM 节点,不容易造成内存泄漏;
  3. 不能遍历,方法有add, delete, has

Map

  1. 本质上是键值对的集合,类似集合;
  2. 是比原生对象更完善的 Hash 数据结构;
  3. 可以遍历,方法很多,非常灵活,可以与各种数据格式转换。

WeakMap

  1. 只接受对象作为键名(null 除外),不接受其他类型的值作为键名;
  2. 键名所指向的对象,不计入垃圾回收机制;
  3. 不能遍历,方法有 get, set, has, delete

对象与 Map

在 ES6 之前,我们经常会使用对象来保存结构化的数据,例如:{ 1: 'Xhy', 2: 'Hyx', 3: 'Yxh' }

但这样做其实缺陷比较大,因为你必须使用字符串作为 key 值,即使我上面的代码使用的是 number 类型,但是 JS 一样会隐式的将其转换为 string 类型。

所幸在 ES2015 标准中,我们拥有了 Map 类型。Map 可以接受任意类型的值作为 key,包括 boolean, Symbol 类型,甚至一个对象也可以成为 Map 的 key 值!Map 是一种比原生 JS 对象更完善的 Hash 结构。

Map

Map 其实就是其他编程语言中常说的:字典。

Map 是一个构造函数,因此我们通过 new Map() 来实例化一个 Map 对象。

  • Map.prototype.set(key, value) 新增元素;
  • Map.prototype.get(key) 读取元素,读取不到就返回 undefined
  • Map.prototype.has(key) 查询元素是否存在,返回 boolean 值;
  • Map.prototype.delete(key) 删除元素,并返回 boolean 值反馈是否删除成功;
  • Map.prototype.clear() 清除 Map 内的所有元素;
  • new Map([iterable]),Map 可以在实例化时接收一个可迭代对象,将其转化为 Map 结构;
  • Map.size 返回 Map 的长度

Map 是可遍历的数据结构,拥有三个遍历器生成函数和一个遍历方法。

  • Map.prototype.keys() 返回 key 的遍历器;
  • Map.prototype.values() 返回值的遍历器;
  • Map.prototype.entries() 返回所有成员的遍历器;
  • Map.prototype.forEach() 遍历 Map 的所有成员。

注意,Map 的遍历顺序就是插入顺序

Set

Set 是集合。他非常类似于数组,但是他的值必须是唯一的,不可重复。

Set 的方法和 Map 的差不多,但少一些:add, delete, has, clear

Set 同样可以在构造时传入一个可迭代对象,将其转化为 Set 结构,并查看 size 属性获取 Set 的成员个数。

同样的,Set 也拥有 keys, values, entires, forEach 四种方法。

注意,Set 的遍历顺序也是插入顺序

WeakMap 与 WeakSet

简单来讲,WeakXXX 结构与 XXX 类似,性质蕾丝。但是,Weak 与非 Weak 版本有两个区别。

  • WeakSet 的成员只能是对象,WeakMap 的键值只能是对象,不能是其他类型的值;
  • WeakXXX 的元素不计入垃圾回收机制

如果我们在对象上存放一些对象,例如 DOM 节点:

const e1 = document.getElementById('foo');
const e2 = document.getElementById('bar'); // 因为对象无法用对象作为 key,所以用数组替代
const arr = [
[e1, 'foo 元素'],
[e2, 'bar 元素'],
];

一旦我们不再需要 e1 和 e2,我们就需要手段删除,不然内存就泄露了。

WeakMap 就是为了解决这个问题而诞生的,它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。

另外:WeakXXX 没有遍历操作。

(完)

对象、Map、Set、WeakMap、WeakSet的更多相关文章

  1. map,set和weakmap,weakset

    概述 set和map属于es6的内容,今天在看书的时候遇到了,所以好好的总结一下,供以后开发时参考,相信对其他人也有用. 参考资料: mdn Keyed collections Map和WeakMap ...

  2. ES6新特性:Javascript中的Map和WeakMap对象

    Map对象 Map对象是一种有对应 键/值 对的对象, JS的Object也是 键/值 对的对象 : ES6中Map相对于Object对象有几个区别: 1:Object对象有原型, 也就是说他有默认的 ...

  3. ES6新增的Map和WeakMap 又是什么玩意?非常详细的解释

    上一篇文章讲了set和weakSet,这节咱就讲Map和weakMap是什么?这两篇文章并没有什么联系,主要知识用法类似而已.嘿嘿,是不是感觉舒服多了. 什么是Map 介绍什么是Map,就不得不说起O ...

  4. Js基础知识7-Es6新增对象Map和set数据结构

    前言 JavaScript中对象的本质是键值对的集合,ES5中的数据结构,主要是用Array和Object,但是键只能是字符串.为了弥补这种缺憾,ES6带来了一种新的数据结构Map. Map也是键值对 ...

  5. Map 和 WeakMap 数据结构

    Map 和 WeakMap 是ES6 新增的数据结构 一.Map 它们本质与对象一样,都是键值对的集合,但是他们与 Object 对象主要的不同是,键可以是各种类型的数值,而Object 对象的键 只 ...

  6. Map和WeakMap的方法和区别

    Map Map是一组键值对的结构,具有极快的查找速度. 一.构造函数不同 let map = new Map(); let weakmap = new WeakMap(); 二.内置函数不同 Map的 ...

  7. Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解

    Jquery遍历筛选数组的几种方法和遍历解析json对象|Map()方法详解 一.Jquery遍历筛选数组 1.jquery grep()筛选遍历数组 $().ready( function(){ v ...

  8. JavaScript基础对象---Map

    一.创建Map对象 Map 对象保存键值对.任何值(对象或者原始值) 都可以作为一个键或一个值 1.构造函数 语法:new Map([iterable])参数:         iterable  可 ...

  9. Map和WeakMap的区别

    个人总结:在一个变量作用域中,如果结束到作用域结尾 } 的话,map中的引用会被垃圾回收机制回收的是weakmap ,map中的引用不会被垃圾回收机制回收的是map. 强引用:只要引用存在,垃圾回收器 ...

  10. ES6 中的 Set、Map 和 WeakMap

    Set 是 ES6 新增的有序列表集合,它不会包含重复项. Set 支持 add(item) 方法,用来向 Set 添加任意类型的元素,如果已经添加过则自动忽略: has(item) 方法用来检测 S ...

随机推荐

  1. synchronized、volatile、CAS 比较?

    1.synchronized 是悲观锁,属于抢占式,会引起其他线程阻塞. 2.volatile 提供多线程共享变量可见性和禁止指令重排序优化. 3.CAS 是基于冲突检测的乐观锁(非阻塞)

  2. resin服务之二----整合resin+Apache服务

    整合resin+Apache服务 1.为什么要整合Apache和resin? a. 早期的resin,tomcat对httpd服务支持不好. b.  tomcat,resin对rewrite,expi ...

  3. Redis报错:DENIED Redis is running in protected mode

    转:Redis使用认证密码登录   Redis默认配置是不需要密码认证的,也就是说只要连接的Redis服务器的host和port正确,就可以连接使用.这在安全性上会有一定的问题,所以需要启用Redis ...

  4. C++中sort()函数使用介绍

    sort()简介 为什么选择使用sort()  在刷题的时候我们经常会碰到排序的问题,如果我们不使用一些排序的方法那我们只能手撕排序,这样就会浪费一些时间.而且我们还需要根据需要去选择相关的排序方法: ...

  5. iView 一周年了,同时发布了 2.0 正式版,但这只是开始...

    两年前,我开始接触 Vue.js 框架,当时就被它的轻量.组件化和友好的 API 所吸引.之后我将 Vue.js 和 Webpack 技术栈引入我的公司(TalkingData)可视化团队,并经过一年 ...

  6. python-输入列表,求列表元素和(eval输入应用)

    在一行中输入列表,输出列表元素的和. 输入格式: 一行中输入列表. 输出格式: 在一行中输出列表元素的和. 输入样例: [3,8,-5] 输出样例: 6 代码: a = eval(input()) t ...

  7. 【Android开发】Coding + git命令行基本使用

    上传代码 进入本地仓库的目录. cd ... 查看仓库链接 : git remote -v 如果没有,则添加url链接 : git remote add testName https://git.co ...

  8. EMS邮箱数据库常用命令(二)

    1.查询邮箱数据库的使用空间 查询Exchange环境中所有邮箱数据库. 键入以下命令 Get-MailboxDatabase -Status | FL name,DatabaseSize 命令执行后 ...

  9. flex布局控制最后一个元素右浮动

    可以在最后一个元素添加css属性 margin-left: auto; 例如我一排排列的元素 ,子元素并没有完全排列撑开父元素的宽度,这时候要使最后一个元素想最右 可以让最后一个元素的 margin- ...

  10. Python入门-面向对象三大特性-封装

    一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容封装到某处 sel ...