ES6深入浅出(三)之Symbol/集合
1, 箭头函数
在介绍箭头函数之前,我们先来认识一下,下面这个四个符合分别代表什么意思
<!-- | 单行注释 |
---|---|
--> | “趋向于“操作符 |
<= | 小于等于 |
=> | ? |
在开始之前,你需要注意的一点:小提示 当使用箭头函数创建普通对象时,你总是需要将对象包裹在小括号里。
var test = Obj.map(item => {}) // 报错 var test = Obj.map(item => ({})) // 用小括号包裹就可以了 复制代码
为什么? 因为在ES6中,一个空对象{}
和一个空的代码块{}
是一样的写法,代码被解析的时候,紧挨着=>之后的 {
被解析为块的开始,而不是对象的开始,所有用一个小括号包裹就可以了
1, 函数的this
普通函数和箭头函数的行为有一个微妙的区别: 箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
注意:通过object.method()语法调用的方法使用非箭头函数定义,这些函数需要从调用者的作用域中获取一个有意义的this值,如果内部函数是一个箭头函数,它继承了外围作用域的this值。
传统写法
{ addAll: function addll(prices) { var self = this; _.each(prices , function(piece) { self.add(price) }) } } 复制代码
ES6写法
{ addAll: function addll(prices) { _.each(pieces, piece => this.add(piece)) } } 复制代码
2, Symbols
JavaScript首次被标注化,那时只有七种原始类型
Undefined 未定义
Null 空值
Boolean 布尔类型
Number 数字类型
String 字符串类型
Object 对象类型
而在ES6新特中,Symbol
也是值,但它不是字符串,也不是对象,而是一种全新的,第七种类型的原始值
Symbol
是程序创建并且可以用作属性键的值,并且它能避免命名冲突的风险。
var mySymbol = Symbol() 复制代码
调用Symbol()
创建一个新的 symbol
,它的值与其它任何值皆不相等。
注意:字符串或数字可以作为属性的键,symbol 也可以,它不等同于任何字符串,因而这个以 symbol 为键的属性可以保证不与任何其它属性产生冲突。
而且:以symbol 为键的属性属性与数组元素类似,不能被类似 obj.name
的点号法访问,你必须使用方括号访问这些属性。
通过上面的说明,那么到底什么是Symbol
typeof Symbol() "symbol" 复制代码
每一个symbol都是独一无二的,不与其他symbol相同,一旦symbol被创建之后,你不能为它设置属性,当可以把它当做属性名称使用。
关于symbol
的忠告:symbol
不能被自动转换为字符 串,这和语言中的其它类型不同。尝试拼接 symbol
与字符串将得到 TypeError
错误。通过String(sym)
或sym.toStr ing()
可以显示地将symbol
转换为一个字符串,从而回避这个问题。
获取symbol的方法
1, 直接调用,返回一个新的唯一的symbol
Symbol() 复制代码
2, 调用同一个,共享同一个 symbol
Symbol.for('str') 复制代码
解释:这种方式会访问 symbol
注册表,其中存储了已经存在的一系列 symbol 。这种方式与通过Symbol()
定义的独立symbol
不同,symbol
注册表中的 symbol
是共享的。如果你连续三十次调用 Symbol.for("str"),每次都会 返回相同的symbol
。注册表非常有用,在多个web
页面或同一个web
页面的多个模块中经常需要共享一个 symbol
。
3, 使用标准定义
Symbol.iterator 复制代码
3, 集合
1, Set
一个 Set 是一群值的集合。它是可变的,能够增删元素
Set和数组的区别:
一个Set不会包含相同的元素
如果添加相同的元素,没有任何作用,效果
var sets = new Set(1,2,3,4) sets.size // 4 sets.add(4) sets.size // 4 复制代码
Set的数据存储专门为一种操作作了速度优化
arrayOfStr.indexOf('zlm') !== -1 // 慢 true setOfStr.has('zlm') // 快 true 复制代码
总结一下:
new Set 创建一个新的空Set
new Set(iterable). 从任何可遍历数据中提取元素,构造出一个新的结合
set.size 获取集合的大小,元素的个数
set.has(value) 判断集合中是否含有指定元素,返回一个布尔值
set.add(value). 添加元素, 如果已经有重复的,不产生效果
set.delete(value). 删除元素,如果不存在,不产生效果
set.clear() 清空集合
2, Map
一个Map对象由若干键值对组成,支持
总结一下:
new Map(). 返回一个新的空Map
new Map(pairs). 根据所含元素形如[key, value] 的数组paris来创建一个新的Map
map.size. 返回Map中项目的个数
map.has(key). 测试一个键名否存在,类似key in obj
map.get(key) 返回一个键名对应的值
map.set(key, value) 添加一对新的键值
map.delete(key). 按照键名删除一项
map.clear(). 清空map
map.keys(). 返回遍历所有键的迭代器
map.value(). 返回遍历所有值的迭代器
map.entries(). 返回遍历所有项的迭代器
小提示: 有一个坏处。Map 和 Set 都为内部的每个键或值保持了强引用,也就是说,如 果一个 DOM 元素被移除了,回收机制无法取回它占用的内存。所以这很可能引发内存泄漏。
ES6也为我们提供了解决方案: 用WeakSet, WeakMap
4, WeakSet, WeakMap
WeakMap 和 WeakSet 与 Map、Set 几乎一样的行为,但是也有区别:
1, WeakMap 只支持 new、has、get、set 和 delete。
2, WeakSet 只支持 new、has、add 和 delete。 3, WeakSet 的值和 WeakMap 的键必须是对象。
4, WeakMap 和 WeakSet都属于弱集合
注意:WeakSet中的对象不计入垃圾回收机制,WeakMap中键名指向的对象不计入垃圾回收机制。
总结: WeakSet和WeakMap没有遍历操作,没有size属性,没有clear方法,WeakSet中的对象是弱引用,WeakMap的键名所引用的对象也是弱引用。垃圾回收机制不将它们的引用考虑在内。一旦不再需要,垃圾回收机制会自动将它们回收,不用手动删除,避免了内存的泄露。
作者:贰拾壹先生
链接:https://juejin.cn/post/7026732214217867271