ES6中Symbol、Set和Map用法详解


Posted in Javascript onAugust 20, 2019

本文实例讲述了ES6中Symbol、Set和Map用法。分享给大家供大家参考,具体如下:

Symbol

1.Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种分别是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object);

2.Symbol 值通过Symbol函数生成,可以作为对象的属性名使用,保证不会与其他属性名产生冲突;

let s = Symbol();
typeof s // symbol

ps:上面代码表示创建一个Symbol变量,值得注意的是,Symbol函数前不能使用new命令,否则会报错,也就是说Symbol 是一个原始类型的值,不是对象,也不能添加属性;

3.Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要用于区分不同的 Symbol 变量;

let s1 = Symbol('a');
let s2 = Symbol('b');
s1.toString() // 'Symbol(a)'
s2.toString() // 'Symbol(b)'

ps:Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的

let s1 = Symbol('a');
let s2 = Symbol('a');
s1 === s2 //false

4.Symbol 值不能与其他类型的值进行运算,但可以转为布尔值,但是不能转为数值;

let s = Symbol();
s + '2'    // Cannot convert a Symbol value to a string
Boolean(s)  // true
!s      // false

5.用于对象的属性名,可以保证不会出现同名的属性,对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖;值得注意的是,Symbol 值作为对象属性名时,不能用点运算符,因为点运算符后面是一个字符串;

let s = Symbol();
let obj = {};
obj[s] = 'hello world';
//或者
let obj = {
  [s] : 'hello world'
}
obj.s  // undefined
obj[s] // hello world

6.Symbol 作为属性名,不会被常规方法遍历得到,即该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回,但是,它并不是私有属性,可以使用 Object.getOwnPropertySymbols 方法,可以获取指定对象的所有 Symbol 属性名;

var obj = {};
var a = Symbol('a');
var b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
obj.c = 'Mine';
for( let key in obj ){
  console.log(key)     // c
}
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols) // [Symbol(a), Symbol(b)]

7.Symbol.for方法接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值。如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值;它与Symbol()不同的是,Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值,而 Symbol()每次都会返回3不同的Symbol值;

Symbol.for("name") === Symbol.for("name")
// true
Symbol("name") === Symbol("name")
// false

8.Symbol.keyFor方法返回一个已登记的 Symbol 类型值的key,而Symbol()写法是没有登记机制的;

var s1 = Symbol.for("name");
Symbol.keyFor(s1) // "name"
var s2 = Symbol("name");
Symbol.keyFor(s2) // undefined

ps:Symbol.for为Symbol值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值

Set 和 Map

1.ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值,它 本身是一个构造函数,用来生成 Set 数据结构。

let s = new Set([1,2,3,4,5,2,2,3,5]);
s // [1,2,3,4,5]

2.可以使用add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果,值得注意的是向Set加入值的时候,不会发生类型转换,即 5 和 "5" 是两个不同的值,但在 Set 内部,两个NaN是相等

let s = new Set([1,2,3]);
s.add(4)  //[1,2,3,4]
s.add(4)  //[1,2,3,4]
s.add(5)  //[1,2,3,4,5]
s.add('5') //[1,2,3,4,5,"5"]
s.add(NaN) //[1,2,3,4,5,"5",NaN]
s.add(NaN) //[1,2,3,4,5,"5",NaN]

3.可以利用Set数据不重复的特性,提供一种新的数组去重方法

// 去除数组的重复成员

[...new Set(array)]
[...new Set([1,2,2,3,3,4,5,5])] //[1,2,3,4,5]

4.Set常见的操作方法有:

add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。

clear():清除所有成员,没有返回值。

s.add(1).add(2).add(2);
// 注意2被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2);
s.has(2) // false

5.Set 结构的实例有四个遍历方法,可以用于遍历成员。

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器

forEach():使用回调函数遍历每个成员
需要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用Set保存一个回调函数列表,调用时就能保证按照添加顺序调用。

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"]

6.ES6 提供了 Map 数据结构,它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适;

7.Map常见的操作方法有:

set(key,val):添加某个值,返回Map结构本身。
get(key):     读取某个键,如果该键未知,则返回undefined
delete(key):  删除某个键,返回一个布尔值,表示删除是否成功。
has(key):     返回一个布尔值,表示该值是否为Map的键。
clear() :      清除所有成员,没有返回值。

const m = new Map();
const o = { str : 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false

8.只有对同一个对象的引用,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

上面例子表明,Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键,因为 k1 和 k2 是两个不同的对象,放在不同的内存地址中,所以Map视为不同的键

9.Map 结构原生提供三个遍历器生成函数和一个遍历方法。

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

ps:Map 的遍历顺序就是插入顺序,这里就不示例了,大家自己动手实践一下。

10.可以使用扩展运算符(...)将Map转换为数组,反过来,将数组传入 Map 构造函数,就可以转为 Map了

//Map转数组
const map = new Map();
map.set('name' , 'hello').set({},'world');
[...map] //[["name","hello"],[{},"world"]]
//数组转Map
const map = new Map([["name","hello"],[{},"world"]]);
map // {"name" => "hello", Object {} => "world"}

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript学习笔记(五) Array 数组类型介绍
Jun 19 Javascript
对于Form表单reset方法的新认识
Mar 05 Javascript
jQuery中trigger()方法用法实例
Jan 19 Javascript
JS基于面向对象实现的放烟花效果
May 07 Javascript
jquery判断密码强度的验证代码
Apr 22 Javascript
javascript基础语法学习笔记
Jan 04 Javascript
js实现对ajax请求面向对象的封装
Jan 08 Javascript
jQuery获得字体颜色16位码的方法
Feb 20 Javascript
jQuery 中ajax异步调用的四种方式
Jun 28 Javascript
JavaScript之Canvas_动力节点Java学院整理
Jul 04 Javascript
Vue实现移动端页面切换效果【推荐】
Nov 13 Javascript
Openlayers实现点闪烁扩散效果
Sep 24 Javascript
Vue+Element UI+vue-quill-editor富文本编辑器及插入图片自定义
Aug 20 #Javascript
node中使用log4js4.x版本记录日志的方法
Aug 20 #Javascript
vue 获取视频时长的实例代码
Aug 20 #Javascript
vue+elementUI实现图片上传功能
Aug 20 #Javascript
vue+elementUi图片上传组件使用详解
Aug 20 #Javascript
vue集成chart.js的实现方法
Aug 20 #Javascript
微信小程序实现定位及到指定位置导航的示例代码
Aug 20 #Javascript
You might like
Zend framework处理一个http请求的流程分析
2010/02/08 PHP
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
php中获取指定IP的物理地址的代码(正则表达式)
2011/06/23 PHP
TMDPHP 模板引擎使用教程
2012/03/13 PHP
yii操作session实例简介
2014/07/31 PHP
php采用curl模仿登录人人网发布动态的方法
2014/11/07 PHP
PHP连接sftp并下载文件的方法教程
2018/08/26 PHP
PHP defined()函数的使用图文详解
2019/07/20 PHP
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
探讨JavaScript语句的执行过程
2016/01/28 Javascript
jQuery中的each()详细介绍(推荐)
2016/05/25 Javascript
js实现div模拟模态对话框展现URL内容
2016/05/27 Javascript
深入理解JavaScript中的预解析
2017/01/04 Javascript
Vue中使用vee-validate表单验证的方法
2018/05/09 Javascript
vuejs 制作背景淡入淡出切换动画的实例
2018/09/01 Javascript
vue swipe自定义组件实现轮播效果
2019/07/03 Javascript
解决Layui中templet中a的onclick参数传递的问题
2019/09/20 Javascript
原生js实现购物车功能
2020/09/23 Javascript
[02:17]2016国际邀请赛中国区预选赛VG战队领队采访
2016/06/26 DOTA
[49:58]完美世界DOTA2联赛PWL S3 Magma vs DLG 第一场 12.18
2020/12/19 DOTA
Python中最常用的操作列表的几种方法归纳
2015/04/24 Python
Python自动登录126邮箱的方法
2015/07/10 Python
Python常用时间操作总结【取得当前时间、时间函数、应用等】
2017/05/11 Python
python自动发送测试报告邮件功能的实现
2019/01/22 Python
利用CSS3的transition属性实现滑动效果
2015/08/05 HTML / CSS
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
反腐倡廉警示教育活动总结
2014/05/05 职场文书
2014大学生批评与自我批评思想汇报
2014/09/21 职场文书
农村党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
2015年市场部工作总结
2015/04/30 职场文书
公司车队管理制度
2015/08/04 职场文书
三八节祝酒词
2015/08/11 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)
2022/01/18 PostgreSQL