ES6 Symbol 是什么

一、是什么

ES6 之前的对象属性都是字符串类型的,像 ​​user.name​​​ ​​user['name']​​​, 这里的 ​​name​​​ 就是属性名。
现在可以使用一种新的数据类型来作为属性名了。

二、特点

  • Symbol 是独一无二的,不会重复。
  • Symbol 不能使用​​new​​​ 生成,直接​​Symbol()​​ 即可。
  • 基本上,它是一种类似于字符串的数据类型。
  • Symbol 值不能跟其它类型的数据运算,会报错

三、使用

Symbol 生成可以直接 Symbol() 但这样生成的 symbol 在打印的时候都是一个样子 Symbol() 不利于区分。

let a = Symbol();
a
// Symbol()

所以为了区分 Symbol 能够接收一个字符串作为参数

let a = Symbol('a')
let b = Symbol('b')
a
// Symbol(a)
b
// Symbol(b)

四、 symbol.description

Symbol(‘这里面就是描述’)
​​​symbol.description​​ 调用

五、作为对象的参数

let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};

六、消除耦合的用处

很多时候,我们需要 switch 一个固定值,但这个值的内容并不重要,像:

const weather = {
sunny: 'sunny',
snow: 'snow',
rain: 'rain'
}

function getWeatherName(weather){
switch (weather){
case 'sunny': return '晴天';
case 'snow': return '下雪';
case 'rain': return '下雨';
}
}

这个例子中的 ​​sunny​​​ 值 ​​'sunny'​​​,没有任何实际意义,只是为了比较。
这里就特别适合用 ​​​Symbol​​​ 唯一且不需要给它指定值。
修改完之后如下:

const weather = {
sunny: Symbol(),
snow: Symbol(),
rain: Symbol()
}

function getWeatherName(weather){
switch (weather){
case weather.sunny: return '晴天';
case weather.snow: return '下雪';
case weather.rain: return '下雨';
}
}

七、遍历

以 ​​Symbol​​​ 作为属性名的属性,并不能通过 ​​forEach()​​​ ​​for..of​​​ 等普通遍历方法遍历出来。
通过 ​​​Object.getOwnPropertySymbols()​​ 获取对象的 Symbol 属性名。

Object.getOwnPropertySymbols(obj)
// [Symbol('a'), Symbol('b')]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-50l9unOh-1606294332098)(media/16062910604950/get-symbol.png)]

八、Symbol.for()

有时候我们定义了一个 ​​symbol​​​,想要再使用的时候就可以通过 ​​Symbol.for('之前定义的名')​​​ 来获取这个 symbol。
​​​Symbol()​​​ 和 ​​Symbol.for()​​ 的区别是:

  • ​Symbol()​​ 每次返回的都是不同值
  • ​Symbol.for()​​ 返回的是同一个值

九、内置 Symbol 值

ES6 内置了一些固定的 Symbol 值

1. Symbol.hasInstance

foo instanceof Foo 
// 等同于
Foo[Symbol.hasInstance](foo)

2. Symbol.iterator

​Symbol.iterator​​ 属性,指向该对象的默认遍历器方法。

… 等等