听说ES6中新增了能够与众不同的Symbol数据类型

300 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

本文同时参与「掘力星计划」,赢取创作大礼包,挑战创作激励金

前言

小伙伴们大家好。不知道大家有没有遇到这样一种情况:在我们日常开发中,有时候可能会用到一些别人提供的对象,并且业务需要想要在这个对象的基础上进行一些扩展,添加一些属性或方法等。这个时候如果我们不了解对象结构的情况下,冒然去扩展,很有可能就会跟对象原有的属性或方法发生冲突。因为在ES5中对象的属性名都是以字符串的形式命名的,这就很容易造成属性名的冲突。而我们接下来要分享的小知识便可以很好的解决这一问题。那就是ES6中新增的一种原始数据类型 - Symbol

原始数据类型Symbol

Symbol是ES6中新增的一种原始数据类型。用它来表示一个独一无二的值。就像我们以前学过的NaN一样,NaN和NaN总是不相等的。同样Symbol和Symbol也总是不相等的。接下来我们看一下Symbol的用法和特点

  • Symbol的用法
    • Symbol的用法很简单,Symbol值是通过Symbol函数生成的。函数可以传递一个字符串类型的参数作为Symbol值的描述
      	let s1 = Symbol();
      	let s2 = Symbol('hello');
      
  • Symbol的特点
    • Symbol的值是独一无二的,每个Symbol值都是不同的
    • Symbol值是通过Symbol函数生成的,Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述
    • Symbol函数如果传递一个对象作为参数,则会调用对象的toString方法将对象转换为字符串
    • Symbol值不能与其他类型值进行运算,否则会报错
    • Symbol 值可以显式转为字符串或布尔值,但是不能转换为数字
    • Symbol作为对象的属性名时需要用方括号[]包裹
    • Symbol值作为对象属性名时,不能用点运算符。需要用:对象名[Symbol变量]的形式访问
    • Symbol类型还可以定义一组常量,以保证这组常量的值都是不相等的
    • Symbol作为对象属性名时,不会出现在for...in、for...of中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回,但是可以通过Object.getOwnPropertySymbols()方法获取Symbol类型的属性名
//1. Symbol的值是独一无二的
//2. Symbol值是通过Symbol函数生成的
let s1 = Symbol();
let s2 = Symbol();
console.log(s1===s2); //false

//3. Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述
let s3 = Symbol('description');
let s4 = Symbol('description');
s3 === s4 ;//false

//4. 给Symbol函数传递一个对象作为参数
let s5 = Symbol([1,2,3])
console.log(s5); // Symbol(1,2,3)

//5. Symbol值不能与其他类型值进行运算
let s6 = Symbol('hello')
console.log(s6 + " world");// TypeError: can't convert symbol to string

//6. Symbol 值可以显式转为字符串或布尔值,但是不能转换为数字
let s7 = Symbol('1')
String(s7);// Symbol(1)
s7.toString();// Symbol(1)
typeof s7 ;// "string"
Boolean(s7) //true
Number(s7);// TypeError: can't convert symbol to number

//7. Symbol作为对象的属性名时需要用方括号[]包裹
//8. Symbol值作为对象属性名时,不能用点运算符。需要用:对象名[Symbol变量]的形式访问
let s8 = Symbol('obj');
let obj = {
	[s8]: 'hello world'
}
console.log(obj.s8);//undefined 这种情况s8会被认为是字符串属性,所以获取不到
console.log(obj[s8]);//hello world

//9. Symbol类型还可以定义一组常量,以保证这组常量的值都是不相等的
const log = {};
log.levels = {
  DEBUG: Symbol('debug'),
  INFO: Symbol('info'),
  WARN: Symbol('warn')
};
console.log(log.levels.DEBUG, 'debug message');
console.log(log.levels.INFO, 'info message');

//10. Symbol作为对象属性名时,不会出现在for...in、for...of中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回,但是可以通过Object.getOwnPropertySymbols()方法获取Symbol类型的属性名
const obj = {};
let a = Symbol('a');
let b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
obj.c = 'javascript'

Object.keys();// ['c']
Object.getOwnPropertySymbols(obj);//[Symbol(a), Symbol(b)]

Symbol的使用场景

了解了Symbol的一些特点后,借助这些特点就可以做一些事情了。比如

  • 扩展其它人提供的对象
  • 消除魔术字符串
  • 为对象定义一些非私有的、但又希望只用于内部的方法
  • 定义一组常量等等

总结

今天我们又学到了ES6中的一个新知识Symbol,相信小伙伴们也感受到了Symbol的强大之处。关于Symbol的使用和特点就分享到这里了。下一篇文章将继续探索Symbol中一些内置的值以及它们的作用。感谢小伙伴们的支持。

喜欢的小伙伴欢迎点赞留言加关注哦!