Bootstrap

ES6 Symbol数据类型

ES6在ES5的6种数据类型(undefined、null、布尔值、字符串、数值、对象)的基础上引入了一种新的数据类型:Symbol。

    在ES6中,Symbol表示独一无二的值,通过Symbol函数生成。

 

注意:Symbol值不是对象,Symbol函数前不可用new命令,不可为Symbol值添加属性。

 

1. Symbol函数可以接收一个字符串作为参数,表示对Symbol实例的描述。

var s1 = Symbol('s1');
console.log(s1); //Symbol(s1)

 

2. Symbol是“独一无二”的。

var s1 = Symbol('s1');
var s2 = Symbol('s1');
console.log(s1 === s2); //false

 

3. Symbol值不可与其他类型值进行运算,不可转换为数值,但可显性转化为字符串或布尔值。

 

注意:Symbol值作为对象属性名时不能使用点运算符。

 

4. 由于Symbol具有独一无二的特性,因此可以用在Switch语句中。

var shapeType = {
     a: 'a',
     b: 'b',
     c: 'c'
};
function getArea(shape) {
   var area = null;
   switch(shape) {
      case shapeType.a:
           area = 1;
           console.log(area);
           break;

      case shapeType.b:
           area = 2;
           console.log(area);
           break;
           
      case shapeType.c:
           area = 3;
           console.log(area);
           break;
    }
}
getArea(shapeType.a); // 1

在上面的代码中,其实shape对象里面的属性a、b、c的值为多少并不重要,因此可以不用实际的值,直接用Symbol值代替即可,Symbol保证了值的唯一性。故可修改如下:

var shapeType = {
    a: Symbol(),
    b: Symbol(),
    c: Symbol()
};
function getArea(shape) {
    var area = null;
    switch(shape) {
       case shapeType.a:
            area = 1;
            console.log(area);
            break;

       case shapeType.b:
            area = 2;
            console.log(area);
            break;
            
       case shapeType.c:
            area = 3;
            console.log(area);
            break;
     }
}
getArea(shapeType.a); // 1

 

5. for ... in、for ... of、object.keys()、Object.getOwnPropertyNames() 无法返回Symbol的属性名,但是Object.getOwnPropertySymbols()和Reflect.ownkeys()方法可以访问到。

var shapeType = {};
var d = Symbol('d');
shapeType[d] = 'd';

for(var index in shapeType) {
   console.log(index);//无输出
}

console.log(Object.getOwnPropertyNames(shapeType));  //[]

console.log(Object.keys(shapeType)); //[]

console.log(Object.getOwnPropertySymbols(shapeType));//[Symbol(d)]

 

6. Symbol.for()、Symbol.keyFor()

    Symbol.for()接受一个字符串作为参数,如果有以该参数作为名称的Symbol值,则返回该Symbol值,如果没有,则新建并返回一个以该字符串为名称的Symbol值。

    Symbol.keyFor()返回一个已登记的Symbol类型值的key。

console.log(Symbol('a') === Symbol('a')); //false
console.log(Symbol.for('a') === Symbol.for('a')); //true

var s1 = Symbol('s1');
console.log(Symbol.keyFor(s1)); //undefined

var s2 = Symbol.for('s2');
console.log(Symbol.keyFor(s2)); //s2

 

7. es6中内置的Symbol值

Symbol.hasInstance:该属性指向一个内部方法,对象使用instanceof运算符时会调用这个方法,判断该对象是否为某个构造函数的实例。

Symbol.isConcatSpreadable:该属性表示一个布尔值,表示该对象使用Object.prototype.concat()时可否展开。

Symbol.species:该属性指向当前对象的构造函数。创建实例时会默认调用这个构造方法。

Symbol.match:该属性指向一个函数,如果该属性存在,执行str.match(myObject)时默认调用该属性指向函数方法的返回值。

Symbol.replace:该属性指向一个方法,当对象被String.prototype.replace方法调用时会返回该方法的返回值。

Symbol.search:该属性指向一个方法,当对象被String.prototype.search方法调用时会返回该方法的返回值。

Symbol.split:该属性指向一个方法,当对象被String.prototype.split方法调用时会返回该方法的返回值。

Symbol.iterator:该属性指向该对象的默认遍历器方法。

Symbol.toPrimitive:该属性指向一个方法,对象被转为原始类型的值时会调用这个方法,返回该对象对应的原始类型值。

Symbol.toStringTag:该属性指向一个方法,在对象调用Object.prototype.toString方法时,如果该属性存在,其返回值会出现在toString方法返回的字符串中,表示对象的类型。

Symbol.unscopables:该属性使with语法块不会在当前作用域下寻找相应的属性。

;