JavaScript7种数据类型:
- undefined
- null
- 布尔值(Boolean)
- 字符串(String)
- 数值(Number)
- 对象(Object)
- Symbol
1. 为什么ES6要引入Symbol?
ES5的对象属性名都是字符串,容易引起属性名冲突,而Symbol保证每个属性名都是独一无二的,从根本上防止属性名冲突。
1 | let s = Symbol(); |
以上代码中,s是一个独一无二的值,typeof判断的结果是s是Symbol数据类型,而不是其他类型
1 | let s1 = Symbol('foo'); let s2 = Symbol('bar'); |
以上代码中s1与s2是两个Symbol值,如果不加参数,则输出都是Symbol(),不利于区分,有了参数,相当于为他们添加了描述,便于区分。
- 当Symbol的参数是一个对象时,就会调用toString方法,转为字符串后生成一个Symbol值。
- Symbol函数的参数只是对当前Symbol值的描述,因此相同参数的Symbol函数的返回值不相等。
- Symbol值不能与其他类型的值进行运算,会报错
- Symbol值可以显示为字符串
- Symbol值也可以转为布尔值,但不能转为数值
2.Symbol.prototype.description
创建Symbol是可以添加一个描述
1 | const sym = Symbol('foo') //sym的描述就是字符串foo |
但读取这个描述要将Symbol显示转为字符串
1 | const sym = Symbol('foo') |
ES2019提供了一个实例属性description,直接返回Symbol描述
1 | const sym = Symbol('foo') |
3.Symbol作为属性名
由于Symbol值都是不相等的,所以Symbol值可以作为标识符,用于对象属性名,可以保证不会出现同名属性
1 | let mySymbol = Symbol() |
以上通过中括号结构和Object.defineProperty,将对象的属性名指定为一个Symbol值
Symbol值作为对象属性名是,不能点运算符
因为点运算符后面总是字符串,所以不会读取Symbol值所代指的值,导致属性名实际上是一个字符串,而不是Symbol值
在对象内部使用Symbol值定义属性时,Symbol值必须放在中括号中,如果不放在中括号中,该属性的键名就是字符串,而不是Symbol值。
Symbol类型还可以用于定义一组常量,保证这组常量的值都是不相等的
Symbol值作为属性名时,该属性是公开属性,不是私有属性
4.属性名的遍历
Symbol作为属性名遍历对象时,该属性不会出现在for…in、for…of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。
但它也不是私有属性,有一个Object.getOwnPropertySymbols()方法可以获取指定对向所有Symbol属性名,该方法返回一个数组,成员是当前对象所有用作属性名的Symbol值。
5.Symbol.for(), Symbol.ketFor()
当我们希望使用同一个Symbol值,Symbol.for()方法可以做到。他接受一个字符串作为参数,然后搜索有没有以该参数作为名称的Symbol值,有则返回这个Symbol值,没有则新建一个以该字符串为名称的Symbol值,并注册到全局。
6.内置Symbol值
除了定义自己使用的Symbol值以外,ES6还提供了11个内置Symbol值,指向语言内部使用方法。
1、 Symbol.hasInstance
对象的Symbol.hasInstance属性,指向一个内部方法。当期他对象使用Instanceof运算符,判断是否为该对象的实例时,会调用这个方法。
2、Symbol.isConcatSpreadable
对象的Symbol.isConcatSpreadable属性等于一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。
3、Symbol.species
对象的Symbol.species属性,指向一个构造函数。创建衍生对象时,会使用该属性。
4、Symbol.match
对象的Symbol.match属性,指向一个函数。当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。
5、Symbol.replace
对象的Symbol.replace属性,指向一个方法,当该对象被String.prototype.replace方法调用时,会返回该方法的返回值。
6、Symbol.search
对象的Symbol.search属性,指向一个方法,当该对象被String.prototype.search方法调用时,会返回该方法的返回值
7、 Symbol.split
对象的Symbol.split属性,指向一个方法,当该对象被String.prototype.split方法调用时,会返回该方法的返回值。
8、Symbol.iterator
对象的Symbol.iterator属性,指向该对象的默认遍历器方法。
9、 Symbol.toPrimitive
对象的Symbol.toPrimitive属性,指向一个方法。该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。
10、 Symbol.toStringTag
对象的Symbol.toStringTag属性,指向一个方法。在该对象上面调用Object.prototype.toString方法时,如果这个属性存在,它的返回值会出现在toString方法返回的字符串之中,表示对象的类型。
11、 Symbol.unscopables
对象的Symbol.unscopables属性,指向一个对象。该对象指定了使用with关键字时,哪些属性会被with环境排除。