首页 > 编程笔记 > JavaScript笔记
阅读:22
JavaScript Symbol类型的用法(附带实例)
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一。
Symbol 值通过 Symbol() 函数生成:
Symbol() 函数可以接收一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者在转换为字符串时比较容易区分。相同参数的 Symbol() 函数的返回值是不相等的。
ES6 之前的对象属性名都是字符串,这容易造成属性名的冲突。比如使用一个第三方提供的对象,但又想对这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。
数据类型 Symbol 可以从根本上防止属性名的冲突。这也是 ES6 设计出 Symbol 的初衷:解决对象的属性名冲突。
Symbol 值作为对象属性名时,不能用点运算符:
同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
【实例】消除魔术字符串。魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码应该尽量消除魔术字符串,改由含义清晰的变量代替。
常用的消除魔术字符串的方法就是把它写成一个变量:
Symbol 值通过 Symbol() 函数生成:
let s1 = Symbol(); // 变量s1是一个独一无二的值 let s2 = Symbol(); // 变量s2是一个独一无二的值 console.log(s1 === s2) // false
Symbol() 函数可以接收一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者在转换为字符串时比较容易区分。相同参数的 Symbol() 函数的返回值是不相等的。
let s1 = Symbol('foo'); // 变量s1是一个独一无二的值 let s2 = Symbol('bar'); // 变量s2是一个独一无二的值 console.log(s1) // Symbol(foo) console.log(s2) // Symbol(bar) console.log(Symbol('foo') === Symbol('foo')) // false
ES6 之前的对象属性名都是字符串,这容易造成属性名的冲突。比如使用一个第三方提供的对象,但又想对这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。
数据类型 Symbol 可以从根本上防止属性名的冲突。这也是 ES6 设计出 Symbol 的初衷:解决对象的属性名冲突。
let mySymbol = Symbol(); // 变量mySymbol是一个独一无二的值 let a = {}; a[mySymbol] = 'Hello!'; console.log(a[mySymbol]); // "Hello!"
Symbol 值作为对象属性名时,不能用点运算符:
const mySymbol = Symbol(); const a = {}; a.mySymbol = 'Hello!'; a['mySymbol'] // undefined a[mySymbol] // "Hello!"在上面代码中,因为点运算符后面总是字符串,所以不会读取 mySymbol 作为标识名所指代的那个值,导致 a 的属性名实际上是一个字符串,而不是一个 Symbol 值。
同理,在对象的内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。
let mySymbol = Symbol(); let a = { [mySymbol]: 'Hello!' };在上面代码中,如果 mySymbol 不放在方括号中,则该属性的键名就是字符串 mySymbol,而不是 mySymbol 所代表的那个 Symbol 值。
【实例】消除魔术字符串。魔术字符串指的是,在代码之中多次出现、与代码形成强耦合的某一个具体的字符串或者数值。风格良好的代码应该尽量消除魔术字符串,改由含义清晰的变量代替。
function isMan(gender) { switch (gender) { case 'man': console.log('男性'); break; case 'woman': console.log('女性'); break } } isMan('man') // 男性在上面代码中,字符串 man 就是一个魔术字符串,它与代码形成“强耦合”,不利于将来的修改和维护。
常用的消除魔术字符串的方法就是把它写成一个变量:
const gender = { man: 'man', woman: 'woman', }在上面代码中,把字符串 man 写成 gender 对象的 man 属性,这样就消除了强耦合。更进一步,可以发现 gender.man 等于哪个值并不重要,只要确保不会跟其他 gender 属性的值冲突即可。因此,这里就很适合改用 Symbol 值。
const gender = { man: Symbol(), woman: Symbol() }在上面代码中,除了将 gender.man 和 gender.woman 的值设为一个 Symbol 之外,其他地方都不用修改。