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 相关文章推荐
document节点对象的获取方式示例介绍
Dec 24 Javascript
bootstrap data与jquery .data
Jul 07 Javascript
javaScript中push函数用法实例分析
Jun 08 Javascript
常用DOM整理
Jun 16 Javascript
JavaScript实现删除,移动和复制文件的方法
Aug 05 Javascript
AngularJS实现全选反选功能
Dec 08 Javascript
laydate.js日期时间选择插件
Jan 04 Javascript
Vue.js递归组件构建树形菜单
Dec 24 Javascript
基于打包工具Webpack进行项目开发实例
May 29 Javascript
JS实现可用滑块滑动的缓动图代码
Sep 01 Javascript
vue选项卡切换登录方式小案例
Sep 27 Javascript
javascript中闭包closure的深入讲解
Mar 03 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
PHP中for循环语句的几种变型
2006/11/26 PHP
php获取当前月与上个月月初及月末时间戳的方法
2016/12/05 PHP
js实现DIV的一些简单控制
2007/06/04 Javascript
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
2011/05/07 Javascript
ASP.NET jQuery 实例6 (实现CheckBoxList成员全选或全取消)
2012/01/13 Javascript
jquery操作select详解(取值,设置选中)
2014/02/07 Javascript
javascript实现复制与粘贴操作实例
2014/10/16 Javascript
javascript实现禁止右键和F12查看源代码
2014/12/26 Javascript
JQUERY简单按钮轮换选中效果实现方法
2015/05/07 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
JS实现带动画的回到顶部效果
2017/12/28 Javascript
Vue多环境代理配置方法思路详解
2019/06/21 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
手把手教你实现 Promise的使用方法
2020/09/02 Javascript
Python查询阿里巴巴关键字排名的方法
2015/07/08 Python
python&MongoDB爬取图书馆借阅记录
2016/02/05 Python
Python中字符串格式化str.format的详细介绍
2017/02/17 Python
python+ffmpeg批量去视频开头的方法
2019/01/09 Python
python 判断矩阵中每行非零个数的方法
2019/01/26 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
python GUI库图形界面开发之PyQt5开发环境配置与基础使用
2020/02/25 Python
Python json模块与jsonpath模块区别详解
2020/03/05 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
Selenium之模拟登录铁路12306的示例代码
2020/07/31 Python
利用纯CSS3实现文字向右循环闪过效果实例(可用于移动端)
2017/06/15 HTML / CSS
KEETSA环保床垫:更好的睡眠,更好的生活!
2016/11/24 全球购物
LivingSocial英国:英国本地优惠
2019/02/22 全球购物
高三自我鉴定怎么写
2013/10/19 职场文书
篮球友谊赛通讯稿
2014/10/10 职场文书
医院领导班子四风问题对照检查材料
2014/10/26 职场文书
2014年村官工作总结
2014/11/24 职场文书
奖励通知
2015/04/22 职场文书
焦裕禄观后感
2015/06/03 职场文书
2015年清剿火患专项行动工作总结
2015/07/27 职场文书
2016年九九重阳节活动总结
2016/04/01 职场文书
ICOM R71E和R72E图文对比解说
2022/04/07 无线电