TOC
ECMAScript 6 简介
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
Symbol
原始数据类型Symbol
- 基本用法:
ES6 引入了一种新的原始数据类型
Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined
、null
、布尔值(Boolean)
、字符串(String)
、数值(Number)
、对象(Object)
。Symbol
值通过Symbol
函数生成。这就是说,对象的属性名现在可以有两种类型,- 一种是原来就有的字符串,
- 另一种就是新增的
Symbol
类型。 凡是属性名属于Symbol
类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。注意,Symbol
函数前不能使用new
命令,否则会报错。这是因为生成的Symbol
是一个原始类型的值,不是对象。
//Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述 let s1 = Symbol('foo'); let s2 = Symbol('bar'); s1 // Symbol(foo) s2 // Symbol(bar) s1.toString() // "Symbol(foo)" s2.toString() // "Symbol(bar)"
Symbol.prototype.description
- 基本用法:
ES2019 提供了一个实例属性
description
,直接返回Symbol
的描述。const sym = Symbol('foo'); sym.description // "foo"
作为属性名的 Symbol
- 基本用法:
由于每一个
Symbol
值都是不相等的,这意味着Symbol
值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。let mySymbol = Symbol(); // 第一种写法 let a = {}; a[mySymbol] = 'Hello!'; // 第二种写法 let a = { [mySymbol]: 'Hello!' }; // 第三种写法 let a = {}; Object.defineProperty(a, mySymbol, { value: 'Hello!' }); // 以上写法都得到同样结果 a[mySymbol] // "Hello!"
Symbol.for(),Symbol.keyFor()
- 基本用法:
Symbol.for()
: 有时,我们希望重新使用同一个Symbol
值,Symbol.for()
方法可以做到这一点。它接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol
值。如果有,就返回这个Symbol
值,否则就新建一个以该字符串为名称的Symbol
值,并将其注册到全局。Symbol.keyFor()
方法返回一个已登记的Symbol
类型值的key
。
//Symbol.for() let s1 = Symbol.for('foo'); let s2 = Symbol.for('foo'); s1 === s2 // true //Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。 //它们的区别是,前者会被登记在全局环境中供搜索,后者不会 Symbol.for("bar") === Symbol.for("bar") // true Symbol("bar") === Symbol("bar") // false //Symbol.keyFor() let s1 = Symbol.for("foo"); Symbol.keyFor(s1) // "foo" let s2 = Symbol("foo"); Symbol.keyFor(s2) // undefined
内置的 Symbol 值
- 基本用法:
Symbol.hasInstance
:对象的Symbol.hasInstance
属性,指向一个内部方法。当其他对象使用instanceof
运算符,判断是否为该对象的实例时,会调用这个方法。Symbol.isConcatSpreadable
:对象的Symbol.isConcatSpreadable
属性等于一个布尔值,表示该对象用于Array.prototype.concat()
时,是否可以展开。Symbol.species
:对象的Symbol.species
属性,指向一个构造函数。创建衍生对象时,会使用该属性。Symbol.match
:对象的Symbol.match
属性,指向一个函数。当执行str.match(myObject)
时,如果该属性存在,会调用它,返回该方法的返回值。Symbol.replace
:对象的Symbol.replace
属性,指向一个方法,当该对象被String.prototype.replace
方法调用时,会返回该方法的返回值。Symbol.search
: 对象的Symbol.search
属性,指向一个方法,当该对象被String.prototype.search
方法调用时,会返回该方法的返回值。Symbol.split
: 对象的Symbol.split
属性,指向一个方法,当该对象被String.prototype.split
方法调用时,会返回该方法的返回值。Symbol.iterator
: 对象的Symbol.iterator
属性,指向该对象的默认遍历器方法。Symbol.toPrimitive
: 对象的Symbol.toPrimitive
属性,指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。Symbol.toStringTag
: 对象的Symbol.toStringTag
属性,指向一个方法。在该对象上面调用Object.prototype.toString
方法时,如果这个属性存在,它的返回值会出现在toString
方法返回的字符串之中,表示对象的类型。Symbol.unscopables
: 对象的Symbol.unscopables
属性,指向一个对象。该对象指定了使用with
关键字时,哪些属性会被with
环境排除。
Set 和 Map 数据结构
Set
- 基本用法:
ES6 提供了新的数据结构
Set
。它类似于数组,但是成员的值都是唯一的,没有重复的值。
// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5
Set
实例的属性:Set.prototype.constructor
:构造函数,默认就是Set
函数。Set.prototype.size
:返回Set
实例的成员总数。
Set
实例的方法:Set.prototype.add(value)
:添加某个值,返回Set
结构本身。Set.prototype.delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set
的成员。Set.prototype.clear()
:清除所有成员,没有返回值。
- 遍历操作:
Set.prototype.keys()
:返回键名的遍历器Set.prototype.values()
:返回键值的遍历器Set.prototype.entries()
:返回键值对的遍历器Set.prototype.forEach()
:使用回调函数遍历每个成员
WeakSet
- 基本用法:
WeakSet
结构与Set
类似,也是不重复的值的集合。但是,它与Set
有两个区别:WeakSet
的成员只能是对象,而不能是其他类型的值。WeakSet
中的对象都是弱引用,即垃圾回收机制不考虑WeakSet
对该对象的引用。 也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet
之中。
这是因为垃圾回收机制依赖引用计数,如果一个值的引用次数不为0,垃圾回收机制就不会释放这块内存。结束使用该值之后,有时会忘记取消引用,导致内存无法释放,进而可能会引发内存泄漏。WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。
由于上面这个特点,WeakSet 的成员是不适合引用的,因为它会随时消失。另外,由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。
Map
- 基本用法:
ES6 提供了
Map
数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
const map = new Map([
['name', '张三'],
['title', 'Author']
]);
Map
实例的属性:Map.prototype.constructor
:构造函数,默认就是Map
函数。Map.prototype.size
:返回Map
实例的成员总数。
Map
实例的方法:Map.prototype.set(key, value)
:set
方法设置键名key
对应的键值为value
,然后返回整个Map
结构。如果key
已经有值,则键值会被更新,否则就新生成该键。Map.prototype.get(key)
:get
方法读取key
对应的键值,如果找不到key
,返回undefined
。Map.prototype.has(key)
:has
方法返回一个布尔值,表示某个键是否在当前Map
对象之中。Map.prototype.delete(key)
:delete
方法删除某个键,返回true
。如果删除失败,返回false
。Map.prototype.clear()
:clear
方法清除所有成员,没有返回值。。
- 遍历操作:
Map.prototype.keys()
:返回键名的遍历器Map.prototype.values()
:返回键值的遍历器Map.prototype.entries()
:返回所有成员的遍历器Map.prototype.forEach()
:遍历Map
的所有成员
WeakMap
- 基本用法:
WeakMap
结构与Map
结构类似,也是用于生成键值对的集合。WeakMap
与Map
的区别有两点:WeakMap
只接受对象作为键名(null
除外),不接受其他类型的值作为键名。WeakMap
的键名所指向的对象,不计入垃圾回收机制。
「下次一定」
下次一定
使用微信扫描二维码完成支付