Symbol
原始数据类型,表示独一无二的值,现共七种数据类型。undefined
、null
、布尔值
、字符串
、Number
、Symbol
和 Object
。
- `Symbol` 函数的参数只是对当前 `Symbol` 值得描述,因此相同参数的 `Symbol` 函数返回值不相等。
```js
Symbol() === Symbol() // false
Symbol('foo') === Symbol('foo) // false
```
- `Symbol` 值不能与其他类型值进行计算
- `Symbol` 可以显示转换为字符串
- `Symbol` 可以转换为布尔值,但是不能转换为数值
- `Symbol` 如果需要读取描述,可以通过 `Symbol('foo').description` 读取 `foo`
- `Symbol` 作为属性名,只能通过 `Object.getOwnPropertySymbols` 方法获取指定对象的所有 `Symbol` 属性名,返回一个数组,成员为当前对象的所有用作属性名的 `Symbol` 值
- 如果希望使用同一个 `Symbol` 值,可以通过 `Symbol.for` 实现
- 对象的 `Symbol.hasInstance` 属性,指向一个内部方法。当其他对象使用 `instanceof` 运算符,判断是否为该对象的实例时,会调用这个方法。
- 对象的 `Symbol.isConcatSpreadable` 属性等于一个布尔值,表示该对象用于 `Array.prototype.concat()` 时,是否可以展开。`Symbol.isConcatSpreadable` 默认等于 `undefined`,也可以展开数组。
```js
let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']
```
- 对象的Symbol.species属性,指向一个构造函数。创建衍生对象时,会使用该属性。`b` 和 `c` 是 `a` 的衍生对象。
```js
class MyArray extends Array {
}
const a = new MyArray(1, 2, 3);
const b = a.map(x => x);
const c = a.filter(x => x > 1);
b instanceof MyArray // true
c instanceof MyArray // true
```
- 对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。
```js
String.prototype.replace(searchValue, replaceValue)
// 等同于
searchValue[Symbol.replace](this, replaceValue)
```
- 对象的 `Symbol.search` 属性,指向一个方法,当该对象被 `String.prototype.search` 方法调用时,会返回该方法的返回值。
- 对象的 `Symbol.split` 属性,指向一个方法,当该对象被 `String.prototype.split` 方法调用时,会返回该方法的返回值。
- 对象的 `Symbol.iterator` 属性,指向该对象的默认遍历器方法。
- 对象的 `Symbol.toPrimitive` 属性,指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。`Symbol.toPrimitive` 被调用时,会接受一个字符串参数,表示当前运算的模式,一共有三种模式。
- Number:该场合需要转成数值
- String:该场合需要转成字符串
- Default:该场合可以转成数值,也可以转成字符串
```js
let obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'
```