ES6中Symbol、Set和Map用法详解

本文实例讲述了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.jb51.net/code/HtmlJsRun测试上述代码运行效果。

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

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

(0)

相关推荐

  • ES6新特性之Symbol类型用法分析

    本文实例讲述了ES6新特性之Symbol类型用法.分享给大家供大家参考,具体如下: Symbol类型 1. 为了避免属性名的冲突,ES6新增了Symbol类型.Symbol可以产生一个独一无二的值. let s1 = Symbol('a'); let s2 = Symbol('a'); console.log(s1); //Symbol(a) console.log(typeof s1); //symbol console.log(s1 == s2); //false 2.Symbol用于属性名

  • ES6概念 Symbol toString()方法

    Symbol toString()方法: 此方法会返回当前symbol对象的字符串表示. 更多关于Symbol的内容可以参阅ES2015 Symbol一章节. 语法结构: symbol.toString(); 代码实例: let s = Symbol("我们"); console.log(s+"欢迎您"); Symbol值不能够隐式转换为字符串类型. let s = Symbol("我们"); console.log(s.toString());

  • ES6中Symbol类型用法实例详解

    本文实例讲述了ES6中的Symbol类型.分享给大家供大家参考,具体如下: Symbol是在ES6中新加入的类型. 正如我们所知,JavaScript中有以下几种类型: Undefined ,Null ,Boolean ,Number ,String, Object. 但是上述类型在处理某些情况的时候是远远不够的.下面我们来举一个例子: 假设我们要移动div,也需要在某些情况下判断该div是否处于移动状态,所以我们会想到给div这类的对象设置一个属性. if (element.isMoving)

  • ES6学习笔记之map、set与数组、对象的对比

    前言 ES5中的数据结构,主要是用Array和Object.在ES6中主要新增了Set和Map数据结构.到目前为止,常用的数据结构有四种Array.Object.Set.Map.下面话不多说了,来一起看看详细的介绍吧. // 数据结构横向对比,增,查,改,删 1.map和数组对比 { let map=new Map(); let array=[]; /**增**/ map.set('t',1); array.push({t:1}); console.info('map-array',map,ar

  • ES6 Symbol数据类型的应用实例分析

    本文实例讲述了ES6 Symbol数据类型的应用.分享给大家供大家参考,具体如下: Symbol,是ES6中引入的新的数据类型,表示独一无二的值.在面向对象中,每个对象都有字符串类型的属性,新方法的名字就有可能与现有方法产生冲突.Symbol的引入保证每个属性的名字都是独一无二的,这样就从根本上防止属性名的冲突. ES6之前对象属性的命名方法 var obj = { name:'Joh', 'my name': 'Johnny' } console.log(obj.name); // Joh c

  • 详解ES6 Symbol 的用途

    Symbol 唯一的用途就是标识对象属性,表明对象支持的功能. 相比于字符属性名,Symbol 的区别在于唯一,可避免名字冲突. 这样 Symbol 就给出了唯一标识类型信息的一种方式,从这个角度看有点类似 C++ 的 Traits. 解决了什么问题 在 JavaScript 中要判断一个对象支持的功能,常常需要做一些 Duck Test. 比如经常需要判断一个对象是否可以按照数组的方式去迭代,这类对象称为 Array-like. lodash 中是这样判断的: function isArray

  • ES6教程之for循环和Map,Set用法分析

    本文实例讲述了ES6教程之for循环和Map,Set用法.分享给大家供大家参考,具体如下: 现在大家先想一想,如果要你遍历一个数组的元素,你会选择如何去做呢?一般都会想起for循环: for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]); } 可惜我得告诉你,这个方法是二十年的人才应该使用的方法,在ES5中已经提出了更为简便的forEach方法,代码如下: myArray.forEac

  • ES6学习笔记之Set和Map数据结构详解

    本文实例讲述了ES6学习笔记之Set和Map数据结构.分享给大家供大家参考,具体如下: 一.Set ES6提供了新的数据结构Set.类似于数组,只不过其成员值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. 1 . Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化. var s = new Set(); var set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] var items =

  • es6 symbol的实现方法示例

    背景 ES5 的对象属性名都是字符串,这容易造成属性名的冲突.比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突.如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突.这就是 ES6 引入Symbol的原因. ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值.它是 JavaScript 语言的第七种数据类型,前六种是:undefined.null.布尔值(Boolean).字

  • ES6概念 Symbol.keyFor()方法

    Symbol.keyFor()方法: 此方法会获取对应Symbol值的键. 更多关于Symbol内容可以参阅ES2015 Symbol一章节. 语法结构: Symbol.keyFor(sym); 参数解析: (1).sym:必需,要获取键值的Symbol值. 代码实例: let s = Symbol.for("我们"); console.log(Symbol.keyFor(s)); 上面的代码可以获取指定Symbol值的键. let s = Symbol("我们")

  • Javascript ES6中数据类型Symbol的使用详解

    介绍 Symbol 是一种特殊的.不可变的数据类型,可以作为对象属性的标识符使用,表示独一无二的值.Symbol 对象是一个 symbol primitive data type 的隐式对象包装器. 它是JavaScript语言的第七种数据类型,前6种分别是:Undefined.Null.Boolean.String.Number.Object. 语法 Symbol([description]) Parameters description : 可选的字符串.可用于调试但不访问符号本身的符号的说

随机推荐