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 相关文章推荐
编辑浪子版表单验证类
May 12 Javascript
锋利的jQuery 要点归纳(二) jQuery中的DOM操作(下)
Mar 23 Javascript
javascript操作JSON的要领总结
Dec 09 Javascript
关于JavaScript中string 的replace
Apr 12 Javascript
jQuery之折叠面板的深入解析
Jun 19 Javascript
简单纯js实现点击切换TAB标签实例
Aug 23 Javascript
jquery实现未经美化的简洁TAB菜单效果
Aug 28 Javascript
使用Vue构建可重用的分页组件
Mar 26 Javascript
Angularjs实现控制器之间通信方式实例总结
Mar 27 Javascript
9102了,你还不会移动端真机调试吗
Mar 25 Javascript
IE浏览器下JS脚本提交表单后,不能自动提示问题解决方法
Jun 04 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 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
8个PHP数组面试题
2015/06/23 PHP
PHP5.2中PDO的简单使用方法
2016/03/25 PHP
php反射学习之依赖注入示例
2019/06/14 PHP
浅谈PHP array_search 和 in_array 函数效率问题
2019/10/15 PHP
图片在浏览器中底部对齐 解决方法之一
2011/11/30 Javascript
jquery实现的网页自动播放声音
2014/04/30 Javascript
删除javascript中注释语句的正则表达式
2014/06/11 Javascript
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
2014/07/15 NodeJs
javascript实现表格排序 编辑 拖拽 缩放
2015/01/02 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
2015/02/13 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
2015/11/04 Javascript
JavaScript-html标题滚动效果的简单实现
2016/09/08 Javascript
使用JQuery选择HTML遍历函数的方法
2016/09/17 Javascript
jquery实现图片切换代码
2016/10/13 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
Javascript网页抢红包外挂实现分享
2018/01/11 Javascript
webpack优化之代码分割与公共代码提取详解
2019/11/22 Javascript
VUE项目axios请求头更改Content-Type操作
2020/07/24 Javascript
Element InputNumber计数器的使用方法
2020/07/27 Javascript
token 机制和实现方式
2020/12/15 Javascript
vue+elementui通用弹窗的实现(新增+编辑)
2021/01/07 Vue.js
python连接mysql并提交mysql事务示例
2014/03/05 Python
在Django的视图中使用数据库查询的方法
2015/07/16 Python
利用Python实现原创工具的Logo与Help
2018/12/03 Python
CSS3中的Transition过度与Animation动画属性使用要点
2016/05/20 HTML / CSS
详解CSS3中字体平滑处理和抗锯齿渲染
2017/03/29 HTML / CSS
高级护理实习生自荐信
2013/09/28 职场文书
大学生学习党课思想汇报
2014/01/03 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
不服从公司安排检讨书
2014/09/24 职场文书
先进个人事迹材料范文
2014/12/30 职场文书
获奖感言一句话
2015/07/31 职场文书
安全教育主题班会教案
2015/08/12 职场文书
2019职场实习报告该怎么写?
2019/07/01 职场文书