ES6之Symbol

1.概述

  ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,我们使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,能够保证每个属性的名字都是独一无二的就好了,这样就能从根本上防止属性名冲突。这就是 ES6引入类型Symbol的原因

  Symbol是一种新的原始数据类型,表示独一无二的值。它是JavaScript语言的第七种数据类型,其他六种分别是:Undefined、Null、Boolean、String、Number、Object。

  Symbol值是通过Symbol函数生成的,也就是说,对象的属性名现在有两种类型:一种是原来就有的字符串;另一种是新增的Symbol类型,只要属性名属于Symbol类型,就是独一无二的,可以保证不会与其他属性名产生冲突。

 如上所示,s是Symbol类型的数据,而不是如字符串之类的其他类型。

  需要注意的是:Symbol函数前不能用new命令,否则会报错,这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

  Symbol函数可以接受一个字符串作为参数,表示对Symbol实例的描述,主要是为了在控制台显示,或者转换为字符串时容易区分。

 

 

以上代码中,s1和s2是两个Symbol值,如果不加参数,控制台输出的都是Symbol(),不利于区分,此时需要加上参数。

如果Symbol的参数是一个对象,就会调用该对象的toString方法,将其转换成字符串,然后才生成一个Symbol值。

  如当传入一个数组和一个对象后,就分别调用了Array和Object的toString方法,将数组和对象分别转换成了字符串再生成了一个Symbol值。实例如下:

 Symbol函数的参数只是对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的。

 且Symbol值不能与其他类型的值进行运算,否则会报错;

 Symbol值可以显示转化成字符串;

Symbol值也可以转化为布尔值;

Symbol值不能转为数值。

2.Symbol作为属性名

  由于每个Symbol值都是不相等的,这意味着Symbol值可以作为标识符用于对象的属性名,保证不会出现同名的属性,这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

var mySymbol=Symbol();

// 第一种写法
var a={};
a[mySymbol]="aaa";

// 第二种写法
var a={
    [mySymbol]:"aaa"
};

// 第三种写法
var a={};
Object.defineProperty(a,mySymbol,{value:"aaa"});

// 以上写法都得到相同的结果
a[mySymbol]="aaa";

需要注意的是:

  (1)Symbol值作为对象属性名时不能使用.运算符。

  (2)Symbol值作为属性名时,该属性还是公开属性,不是私有属性。

本文摘自《ES6标准入门(第三版)阮一峰著》

原文地址:https://www.cnblogs.com/codexlx/p/12579654.html