基本概念
Symbol:表示独一无二的值,属于类字符串数据类型,本质上可以当字符串来用。
基本用法
- Symbol是JavaScript的第七种数据类型,前六种分别是undefined、null、Boolean、String、NUmber、Objects、Symbol。
// 1
let symbol = Symbol();
typeof symbol
// symbol
// 2 Symbol使用时不能使用new,它是一个函数,可以接收参数,仅作为描述
let symbol1 = Symbol('week');
symbol1;
// Symbol(week)
symbol1.toString();
// "Symbol(week)"
// 3
let symbol1 = Symbol();
let symbol2 = Symbol();
symbol1 === symbol2;
// false
let symbol1 = Symbol('object');
let symbol2 = Symbol('object');
symbol1 === symbol2;
// false
// 4 隐式转换
const obj = {
toString() {
return 'object';
}
};
const symbol = Symbol(obj);
symbol;
// Symbol(object)
// 5 不能参与运算
let symbol = Symbol('symbol');
"hello" + symbol;
// TypeError: Cannot convert a Symbol value to a string
// 6 类型转换
String(symbol);
symbol.toString();
// Symbol(symbol)
let symbol = Symbol();
Boolean(symbol);
// true
Number(symbol);
// TypeError: Cannot convert a Symbol value to a number
- description ,Symbol的描述
const symbol = Symbol('symbollobmys');
symbol.description;
// "symbol"
- symbol应用场景,对象属性名
let symbol = Symbol();
let a = {};
a[symbol] = 'Hello!';
let a = {
[symbol]: 'Hello!'
};
let a = {};
Object.defineProperty(
a,
symbol,
{
value: 'Hello!'
}
);
- 属性遍历
属性遍历中的for...in、for...of、Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()都不会返回Symbol,它们会把Symbol过滤掉。但是我们可以有两种方法得到Symbol,一种是Object.getOwnPropertySymbols,另一种是Reflect.ownKeys。
const obj = {};
let symbol1 = Symbol('symbol1');
let symbol2 = Symbol('symbol2');
obj[symbol1] = 'symbol1';
obj[symbol2] = 'symbol1';
Object.getOwnPropertySymbols(obj);
// [Symbol(symbol1), Symbol(symbol2)]
Reflect.ownKeys(obj);
// [Symbol(symbol1), Symbol(symbol2)]
// 可以作为非私有的内部方法
- Symbol.for(是唯一一个能让两个Symbol相等的),寻找全局的环境下某个描述下面的这个Symbol,如果找到某一个描述下的Symbol,那么就会返回这个Symbol,如果没有找到就会生成一个新的Symbol。简而言之就是,返回当前索引Symbol。
let symbol1 = Symbol.for('week');
let symbol2 = Symbol.for('week');
symbol1 === symbol2;
- Symbol.keyFor,返回已登记的Symbol的key
let symbol1 = Symbol.for("symbol1");
Symbol.keyFor(symbol1);
// symbol1
let symbol2 = Symbol("week");
Symbol.keyFor(symbol2);
// undefined
内置的Symbol
-
Symbol.hasInstance
,instanceof运算符调用
class MyClass {
[Symbol.hasInstance](obj) {
return obj instanceof Array;
}
}
[1, 2, 3] instanceof new MyClass();
// true
-
Symbol.isConcatSpreadable
,控制数组concat是否展开
let array1 = [1, 2];
[3, 4].concat(array1, 5);
// ['a', 'b', 'c', 'd', 'e']
array1[Symbol.isConcatSpreadable];
// undefined
let array2 = [1, 2];
array2[Symbol.isConcatSpreadable] = false;
[3, 4].concat(array2, 5);
// [3, 4, [1, 2], 5]
-
Symbol.species
,为衍生类指定原型
class MyArray extends Array {
}
const one = new MyArray(1, 2, 3);
const two = a.map(x => x);
const three = a.filter(x => x = 1);
b instanceof MyArray;
// true
c instanceof MyArray;
// true
class MyArray extends Array {
static get [Symbol.species]() { return Array; }
}
const one = new MyArray(1, 2, 3);
const two = a.map(x => x);
const three = a.filter(x => x = 1);
b instanceof MyArray;
// false
c instanceof Array;
// true
-
Symbol.match
,str.match调用
class Mather {
[Symbol.match](string) {
return 'hello world';
}
}
'e'.match(new Mather());
// 'hello world'
-
Symbol.replace
,replace调用
const demo = {};
demo[Symbol.replace] = () => 'hello word';
'Hello'.replace(demo, 'World');
// hello word
Symbol.search
Symbol.split
-
Symbol.iterator
,默认遍历器
const diyIterable = {};
diyIterable[Symbol.iterator] = function* () {
yield 'hello';
yield 'word';
};
[...diyIterable];
// ['hello', 'word']
-
Symbol.toPrimitive
,类型转换调用
let object = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 1;
case 'string':
return 'hello';
case 'default':
return 'word';
default:
throw new Error('Cannot convert');
}
}
};
2 * object;
// 2
3 + object;
// '3word'
object == 'word';
// true
String(object);
// hello
-
Symbol.toStringTag
, 指定[object Object]或[object Array]中object后面字符串
({
[Symbol.toStringTag]: 'Hello'
}.toString())
// "[object Hello]"
-
Symbol.unscopables
, 指定被with排除的属性,with是一个语句,它可以扩展一个作用域链
// with语句 扩展一个语句的作用域链
var a, x, y;
var r = 10;
with (Math) {
a = PI * r * r;
x = r * cos(PI);
y = r * sin(PI / 2);
}
class MyClass {
week() {
return 1;
}
get [Symbol.unscopables]() {
return { week: true };
}
}
var week = function () { return 2; };
with (MyClass.prototype) {
week();
// 2
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。