Symbol应该是JS中全新的概念,相当于给JS添加了一种新的类型,我们知道JS有6种类型,以typeof出来的结果为准:string,number,boolean,object,function,undefined。现在多了一种symbol类型,这些类型还可以分成值类型和引用类型,symbol更倾向是值类型。
规范中对于Symbol的介绍在6.1.5章节,简单看一下:
The Symbol type is the set of all non-String values that may be used as the key of an Object property (6.1.7).
Each possible Symbol value is unique and immutable.
Each Symbol value immutably holds an associated value called [[Description]] that is either undefined or a String value.
通过上面的描述可以看出Symbol是不可变的,这也是为什么说symbol类型更像是值类型。
这篇文章主要介绍一下Symbol的基本用法,后面还有更详细的文章介绍它的API和内置的Symbols用法。
typeof Symbol()//"symbol"
var sym = Symbol( "description" );//注意不使用new
sym instanceof Symbol; // false,值类型的特征,"123" instanceof String 也是false
var symObj = Object( sym );
symObj instanceof Symbol; // true
symObj.valueOf() === sym; // true
Symbol类型的一个重要用途就是作为不可变且唯一的常量来用,看个例子:
const MOOD_BLUE = 'BLUE';
const FAKED_BLUE = 'BLUE';
MOOD_BLUE === FAKED_BLUE //true
const COLOR_RED = Symbol();
const FAKED_RED = Symbol()
COLOR_RED === FAKED_RED //false
通过上面的例子可以看出,每个Symbol都是唯一的,比常量字符串更适合用作唯一的key。
Symbol还有一个重要的用法就是作为Object对象的key,下面是个简单的例子,以后的iterator也是用这种形式实现的:
const sym = Symbol('yes');
let obj = {
[sym]: 'a',
str: 'b',
};
console.log(obj[sym])//'a'
//我们要想获取对象里的所有symbol类型key,需要:
Object.getOwnPropertySymbols(obj);
//通过for-in或者Object.keys都是不能获得symbol类型的key,还有一个API可以,后面在具体介绍:
Reflect.ownKeys(obj)
下面我们看一下symbol类型向其它值类型的转换情况:
同样parseInt(Symbol())也会报错,TypeError,不会是NaN,需要记住。
还有一点就是不能new一个Symbol出来,这一点也说明了它更像值类型:
new Symbol()//TypeError: Symbol is not a constructor
ES6内置了一些所谓的well-know symbols,这里列举一下,后面在详细讲:
Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.iterator
Symbol.match
Symbol.replace
Symbol.search
Symbol.species
Symbol.split
Symbol.toPrimitive
Symbol.toStringTag
Symbol.unscopables
*以上全部代码在Firefox 43下通过测试