symbol是es6新增的一种原始类型。用作非字符串的属性全名。
你想理解符号吗?
想要理解符号,需要了解Javascript的基础类型Object是一个无序的集合,其中每个属性都有一个名字和一个值。属性名通常是(在es6之前 必须是字符串)字符串。但在es6之后包括es6版本,符号也可以作为属性名。
作为es6新贵,他有什么特别之处?
创建一个Symbol类型不需要用new操作符,否则会报错,因为生成的 Symbol 是一个原始类型的值,不是对象。直接let s = Symbol();测试s就是Symbol类型了。怎么说他是唯一的呢?
let s = Symbol(); let ss = Symbol(); s == ss ; 结果是false
或者
let s = Symbol('a'); let ss = Symbol('a'); s == ss ; 结果是false
通过以上的比较,我们对Symbol的唯一性,有了一定的了解。也就是说当你创建了一个Symbol数据后,那么你就是独一无二的存在了,是的就是这样。
2、数据类型的修饰
有人会好奇Symbol('a')里面的参数a又是怎么回事呢?字符串a表示一种修饰,对你当前创建的Symbol类型的一种修饰,作为区分使用,否则当你创建多个Symbol数据时,容易混淆。
3、与其他数据类型之间的转换
Symbol不能用四则运算进行操作,否则报错。它只能用显示的方式转为字符串和布尔值,即:String(Symbol()) / Boolean(Symbol())
4、作为对象的属性
a、作为对象的属性时,注意要用以下三种方式来书写:
let mySymbol = Symbol();
1
// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';
1
2
// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
1
2
3
// 第三种写法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
1
2
以上的都可以得到 a[mySymbol] // “Hello!”
b、对象属性的遍历
以上说了对象属性的创建,但是我们要格外的注意,Symbol 作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回。所以我们可以用Object.getOwnPropertySymbols方法,获取指定对象的所有 Symbol 属性名。
看到这是不是感觉用Symbol类型创建的对象属性这么麻烦吗?如果一个对象里面有字符串的属性又有Symbol的属性,难不成要分来获取对象属性吗?答案是不用,那必须使用新的API方法:Reflect.ownKeys(),这个方法就可以返回对象所有的属性,也就是字符串属性和Symbol属性。所以这里要留意了。
5、Symbol.for(),Symbol.keyFor()
有时,我们希望重新使用同一个 Symbol 值,以上我们都说了Symbol数据类型是唯一的,所有只用Symbol()方法创建的Symbol类型是无法实现的。所有我们可以用Symbol.for()这个方法来实现。
let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');
s1 === s2 // true
1
2
3
注意,这里的Symbol.for()和Symbol()创建的都是Symbol类型,但是他们的创建机制有所不同,Symbol.for('a')的创建方式会在创建之前在全局中寻找,有没有用Symbol.for()的方式,并且key是'a'的字符串创建了Symbol类型(创建了就会在全局中登记),如果有则不重复创建,直接用已创建的(已登记的)。然而Symbol('a')的创建是不会去检索全局的,是直接创建一个新的Symbol类型。这也是用Symbol('a')创建的两个Symbol类型不相等的根本原因。
Symbol.keyFor()方法返回一个已登记的 Symbol 类型值的key。
let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"
let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
1
2
3
4
5
上面代码中,变量s2属于未登记的 Symbol 值,所以返回undefined。也就是说Symbol.keyFor()这个方法,主要服务于Symbol.for()的。因为Symbol()方法创建的值用Symbol.keyFor()永远是undefined。