Symbol(符号)
一. 概念
是一种新的数据类型,值之间互不等
<html>
<span style='color:red'>注:Symbol为生产Symbol类型数据的函数,而不是数据类型本身</span>
</html>
值类型而非引用类型
var a = new Symbol() // throw err
var b = Symbol()
typeof b // symbol
只可通过Object.getOwnPropertySymbols获取
for in、for of、Object.keys()、Object.getOwnPropertyNames()、无法遍历出symbol属性
var a = Symbol()
var b = {}
b[a] = "hehe"
Object.keys(b) // [],数组为空
Object.getOwnPropertySymbols() // [ Symbol() ]
<html>
<span style='color:red'>注:所有引用类型数据都是通过new操作符产生的,因此使用new操作符报错可证明其数据类型为值类型</span>
</html>
二. 语法
1. 使用Symbol函数生成Symbol类型值
// 局部Symbol
var a = Symbol()
var b = Symbol('symbol')
var c = Symbol('symbol')
a === b // false
b === c // false
c === a // false
2. 注册全局可重用Symbol
// 全局Symbol
// 全局注册key1与key2
var key1 = Symbol.for('key1')
var key2 = Symbol.for('key2')
key1 === key2 // false
// 从全局获取key2键对应的Symbol
var tempKey2 = Symbol.for('key2')
key2 === tempKey2 // true
// 通过Symbol获取全局表中对应的key
console.log(Symbol.keyFor(key2)) // key2
三. 用途
1. 防冲突
- 第三方库的命名冲突
- 状态管理中状态冲突
- 与标准api冲突
2. 枚举
四. 内置Symbol
symbol内置在了许多对象中作为属性名称,会在特定情况下触发
描述 | 含义 |
---|---|
Symbol.iterator | 用于为对象定义一个方法并返回一个属于所对应对象的迭代器,该迭代器会被for-of循环语句所使用 |
Symbol.hasInstance | 用于为类定义一个方法,该方法会因为instanceof语句的使用而被调用,来检查一个对西那个是否是某一个类的实例 |
Symbol.match | 用于为正则表达式定义一个可被String.prototype.match方法使用的方法,检查对应的字符串与当前正则表达式是否匹配 |
Symbol.replace | 用于为正则表达式或对象定义一个方法。该方法会因为String.prototype.replace方法的使用而被调用,用于处理当字符串使用该正则表达式或对象作为替换标志时的内部处理逻辑 |
Symbol.search | 用于为正则表达式或对象定义一个方法。该方法会因为String.prototype.replace方法的使用而被调用,用于处理当字符串使用该正则表达式或对象作为位置索引标志时的内部处理逻辑 |
Symbol.split | 用于为正则表达式或对象定义一个方法。该方法会因为String.prototype.replace方法的使用而被调用,用于处理当字符串使用该正则表达式或对象作为分割标志时的内部处理逻辑 |
Symbol.unscopables | 用于为对象定义一个属性。该属性用于决定该对象中哪些属性是可以被with语句所使用的 |
Symbol.isConcatSpreadable | 用于对对西那个定义一个属性。该属性用于决定该对西那个作为Array.prototype.concat()方法的参数时,是否会被展开 |
Symbol.species | 用于为类定义定义一个静态属性。该属性用于决定该类的默认构建函数 |
Symbol.toPrimitive | 用于为对象定义一个方法。该方法会在该对象需要转换为值类型的时候被调用,可以根据程序的行为决定该对象需要被转换成的值 |
Symbol.toStringTag | 用于为类定义一个属性。该属性可以决定这个类的实例在调用toString方法时,其中的标签内容 |
1. Symbol.iterator
es6标准定义了可迭代对象和新的for-of循环语句,其中可迭代对象不是一种类型,而是带有@@iterator属性和可以被for-of循环语句所遍历的对象统称。
定义一个可迭代对象
可迭代对象都会使用Symbol.iterator作为方法名的方法属性,该方法会返回一个迭代器
/**
* 迭代器是一个含有next方法的对象
* next方法返回一个迭代状态对象,含有value与done值
* 最后一次返回状态值为undefined
/
let obj = {
[Symbol.iterator]() {
return {
next() {
return {
value: 'value',
done: false,
}
}
}
}
}
2. Symbol.hasInstance
对象的Symbol.hasInstance属性,指向一个内部方法。当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
3. Symbol.match
对象的Symbol.match属性,指向一个函数。当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。