阅读 118

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


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐