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 相关文章推荐
jQuery实现 注册时选择阅读条款 左右移动
Apr 11 Javascript
jquery ajax jsonp跨域调用实例代码
Dec 11 Javascript
javascript模拟实现ajax加载框实例
Oct 15 Javascript
45个JavaScript编程注意事项、技巧大全
Feb 11 Javascript
JavaScript弹出新窗口后向父窗口输出内容的方法
Apr 06 Javascript
JS、jQuery中select的用法详解
Apr 21 Javascript
PassWord输入框代码分享
Jun 07 Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
Aug 29 Javascript
JS自动生成动态HTML验证码页面
Jun 14 Javascript
解决微信小程序中的滚动穿透问题
Sep 16 Javascript
Vue 嵌套路由使用总结(推荐)
Jan 13 Javascript
js实现筛选功能
Nov 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
PHP写的获取各搜索蜘蛛爬行记录代码
2012/08/21 PHP
PHP获取和操作配置文件php.ini的几个函数介绍
2013/06/24 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
Zend Framework教程之配置文件application.ini解析
2016/03/10 PHP
ThinkPHP 框架实现的读取excel导入数据库操作示例
2020/04/14 PHP
PHP获取类私有属性的3种方法
2020/09/10 PHP
Javascript实现的分页函数
2006/12/22 Javascript
基于jquery库的tab新形式使用
2012/11/16 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
详解AngularJS中自定义指令的使用
2015/06/17 Javascript
浅析AngularJS中的指令
2016/03/20 Javascript
老生常谈JQuery data方法的使用
2016/09/09 Javascript
利用Node.JS实现邮件发送功能
2016/10/21 Javascript
将json转换成struts参数的方法
2016/11/08 Javascript
node.js程序作为服务并在windows下开机自启动(用forever)
2017/03/29 Javascript
AngularJS中下拉框的高级用法示例
2017/10/11 Javascript
webpack 模块热替换原理
2018/04/09 Javascript
vue-cli V3.0版本的使用详解
2018/10/24 Javascript
angular 实现下拉列表组件的示例代码
2019/03/09 Javascript
解决layui的input独占一行的问题
2019/09/10 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
2020/07/19 Javascript
python爬虫入门教程之糗百图片爬虫代码分享
2014/09/02 Python
Python类的多重继承问题深入分析
2014/11/09 Python
解读! Python在人工智能中的作用
2017/11/14 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
python 基于opencv 绘制图像轮廓
2020/12/11 Python
解决pycharm修改代码后第一次运行不生效的问题
2021/02/06 Python
Luxplus丹麦:香水和个人护理折扣
2018/04/23 全球购物
Holland & Barrett爱尔兰:英国领先的健康零售商
2019/03/31 全球购物
小学生暑假家长评语
2014/04/17 职场文书
文员试用期转正自我鉴定
2014/09/14 职场文书
合作协议书范本
2014/10/25 职场文书
2014年小学数学教师工作总结
2014/12/03 职场文书
档案接收函格式
2015/01/30 职场文书
2015年师德师风自我评价范文
2015/03/05 职场文书
建筑质检员岗位职责
2015/04/08 职场文书