es6的Symbol

ES6中引入了一种新的数据类型:Symbol,可以作为对象属性的标识符使用;

ES6引入Symbol的原因:防止属性名的冲突(ES5的对象属性名都是字符串,容易造成属性名的冲突);

Symbol值不能与其他类型的值进行运算;

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

Symbol不能使用new命令,否则会报错,因为Symbol是一个原始类型的值,不是对象;

在js文件中定义的Symbol,不能在其他文件中共享;

每个Symbol实例都是唯一的。因此,当你比较两个Symbol实例的时候,将总会返回false:

let s1 = Symbol()
let s2 = Symbol('another symbol')
let s3 = Symbol('another symbol')

s1 === s2 // false
s2 === s3 // false

Symbol值可以转为字符串:

var sym = Symbol('My symbol');

String(sym);   // 'Symbol(My symbol)'
sym.toString();   // 'Symbol(My symbol)'

Symbol值作为对象属性名时,不能用点运算符:

var mySymbol = Symbol();
var a = {};

a.mySymbol = 'Hello!';
a[mySymbol]   // undefined
a['mySymbol']   // "Hello!"

上面代码中,因为点运算符后面总是字符串,所以不会读取mySymbol作为标识名所指代的那个值,导致a的属性名实际上是一个字符串,而不是一个Symbol值。

同理,在对象的内部,使用Symbol值定义属性时,Symbol值必须放在方括号之中。下面代码中,如果s不放在方括号中,该属性的键名就是字符串s,而不是s所代表的那个Symbol值:

let s = Symbol();

let obj = {
  [s]: 1
};

属性名的遍历

Symbol作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有Symbol属性名。

Reflect.ownKeys方法可以返回所有类型的属性名,包括常规的和Symbol属性名。

原文地址:https://www.cnblogs.com/xjy20170907/p/12683902.html