# Symbol 类型
WARNING
- 基础
- 作为属性名
- 属性名的遍历
- Symbol.for 和 Symbol.keyFor
- 11个内置 Symbol 值
可以用来表示独一无二的值
let s1 = Symbol('xiao')
let s2 = Symbol('xiao')
console.log(s1 === s2) // false
1
2
3
2
3
不可以和其他类型的值做运算
let s2 = Symbol('xiao')
2 + s2
1
2
2

可以转换成字符串类型和布尔类型
let s2 = Symbol('xiao')
console.log(s2.toString()) // Symbol(xiao)
console.log(Boolean(s2)) // true
1
2
3
2
3
可以用作属性名,使用 symbol 作为属性名的好处就是独一无二不会被覆盖。
// 对象属性名
let prop = 'name'
let objSymbol = {
name: '小鱼',
[`my${prop}`]: '小铜钱'
}
let s3 = Symbol('name')
let objSymbol2 = {
[s3]: '你好'
}
// 修改值
objSymbol2[s3] = '修改了'
// objSymbol2.s3 不能这么修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
属性名的遍历
let objSymbol2 = {
[s3]: '你好',
age: 19
}
for (let key in objSymbol2) {
console.log(key, 'key--') // 只有 age
}
console.log(Object.keys(objSymbol2), '属性名') // ['age'] 只有 age
console.log(Object.getOwnPropertyNames(objSymbol2)) // ['age'] 只有 age
console.log(JSON.stringify(objSymbol2)) // {"age":19}
// 获取symbol属性
console.log(Object.getOwnPropertySymbols(objSymbol2))
// 获取所有属性名
console.log(Reflect.ownKeys(objSymbol2)) // ['age', Symbol(name)]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Symbol.for 方法
使用 Symbol.for() 创建的时候,会先查找是否已经创建过了,如果是则返回
let s4 = Symbol.for('xiao')
let s5 = Symbol.for('xiao')
console.log(s4 === s5) // true
1
2
3
4
5
2
3
4
5
Symbol.keyFor() 返回一个标识
let s4 = Symbol.for('xiao')
console.log(Symbol.keyFor(s4)) // xiao
1
2
2
# 11 个内置的 Symbol 值
Symbol.hasInstance
let obj2 = {
[Symbol.hasInstance](otherObj: any) {
console.log(otherObj, '实例') // { a: '1' }
}
}
console.log({ a: '1' } instanceof <any>obj2, '测试-a') // false
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Symbol.isConcatSpreadable 可读写的布尔值,默认是 undefined, 是否可扁平化
let arr = [1, 2]
console.log([].concat(arr, [3, 4])) // [1, 2, 3, 4]
arr[Symbol.isConcatSpreadable] = false
console.log([].concat(arr, [3, 4])) // 此时不会被扁平化了
1
2
3
4
2
3
4
Symbol.species 可以指定衍生对象的构造函数
class C extends Array {
getName () {
return 'xiao'
}
}
const c = new C(1, 2, 3)
const a = c.map(item => {
return item + 1
})
c instanceof C // true
c instanceof Array // true
a instanceof C // true
a instanceof Array // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
class C extends Array {
constructor(...args) {
super(...args);
}
static get[Symbol.species]() {
return Array
}
getName () {
return 'xiao'
}
}
const c = new C(1, 2, 3)
const a = c.map(item => {
return item + 1
})
c instanceof C // true
c instanceof Array // true
a instanceof C // false 这里是有区别的
a instanceof Array // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Symbol.match
let obj3 = {
[Symbol.match](str: string) {
console.log(str.length)
}
}
'abc2'.match(<RegExp>obj3) // 4
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Symbol.replace 、Symbol.search 、Symbol.split 和上面的 match 都是使用在字符串上的方法
Symbol.iterator 数组是否可迭代
let arrD = [1, 2, 3]
let iterator = arrD[Symbol.iterator]()
iterator.next() // { value: 1, done: false }
iterator.next() // { value: 2, done: false }
iterator.next() // { value: 3, done: false }
iterator.next() // { value: undefined, done: true }
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Symbol.toPrimitive 对象被转成原始类型值的时候,会调用这个方法。(隐式类型转换)
let objStr = {
[Symbol.toPrimitive](type) {
console.log(type, '类型') // number
}
}
let res = objStr++
1
2
3
4
5
6
7
2
3
4
5
6
7
let objStr = {
[Symbol.toPrimitive](type) {
console.log(type, '类型') // string
}
}
let resStr = `abc${objStr}`
1
2
3
4
5
6
2
3
4
5
6
Symbol.toStringTag 可以指定属性值, 对象调用 toString 的时候,会调用 toStringTag
let objStr = {
[Symbol.toStringTag]: 'xiao'
}
console.log(objStr.toString()) // [object xiao]
1
2
3
4
2
3
4
let objStr = {
get [Symbol.toStringTag]() {
return 'xiao'
}
}
console.log(objStr.toString()) // [object xiao]
1
2
3
4
5
6
2
3
4
5
6
Symbol.unscopables 和 with 有关
let objData = {
a: 'a-1',
b: 'b-1'
}
with (objData) {
console.log(a) // a-1
console.log(b) // b-1
}
console.log(Array.prototype[Symbol.unscopables])
// 数组被过滤的掉的方法
at: true
copyWithin: true
entries: true
fill: true
find: true
findIndex: true
findLast: true
findLastIndex: true
flat: true
flatMap: true
includes: true
keys: true
values: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24