ES6中的Symbol基础

150 阅读3分钟

Symbol

symbol是es6提出了的一种原始数据类型,用来表示独一无二的值。并且不可以通过new关键字创建。

symbol可以通过symbol()这个函数创建。

Symbol的一些基本知识

Symbol的创建

var s = Symbol();
console.log(s); // Symbol()
console.log(typeof s); // symbol

给Symbol附带一个参数进行创建

是不是很奇怪,为什么我们定义了一个Symbol类型的值,但是我们没有给那个symbol变量赋值,最后却输出了一个Symbol()。这个其实只是一个标记,如果我们在使用Symbol这个函数创建变量的时候,传入一个参数,那么最后输出的时候,这个参数就会带着输出,这样就可以方便我么分别不同的Symbol值。

就像这样:

var s2 = Symbol("我是一个Symbol类型");
console.log(s2);  // Symbol(我是一个Symbol类型)

不能使用new关键字创建

前面我们提到,Symbol是通过Symbol这个函数进行创建的,Symbol并不是一个对象,而是一个基本数据类型,如果使用new关键字进行创建就会报错。

var s3 = new Symbol();

报错信息:

var s3 = new Symbol();
         ^
TypeError: Symbol is not a constructor
    at new Symbol (<anonymous>)

这就证明我们创建Symbol不能通过new关键字创建。

如果Symbol创建传参为一个对象,则输出时使用toString()方法将内容输出

var obj = {
    toString() {
        return '海绵宝宝';
    }
};
var s4 = Symbol(obj);
console.log(s4); // Symbol(海绵宝宝)

最后输出的结果就是:Symbol(海绵宝宝)

每一个Symbol都是独一无二的

尽管我们给多个Symbol函数传入相同的参数,但是他们却是不相等的。

var s5 = Symbol("test");
var s6 = Symbol("test");
console.log(s5 === s6);  // false

可以看到最后的结果是false,这是因为Symbol出现的原因就是为了解决每个变量都不同的问题。

Symbol不可以与其他数据类型进行运算

这个Symbol不能与其他数据类型进行运算,包括其本身也不行。

var s6 = Symbol("12");
var s7 = Symbol("34");
console.log(s6 + s7);

报错:

console.log(s6 + s7);
               ^
TypeError: Cannot convert a Symbol value to a number

Symbol可以显示转换为字符串

也就是说我们可以直接将Symbol类型的值调用String方法直接转换为字符串。

var s8 = Symbol("海绵宝宝");
console.log(String(s8));  // 'Symbol("海绵宝宝")'
console.log(s8.toString()); // 'Symbol("海绵宝宝")'

注意:

Symbol作为对象不会出现在 for...in、for...of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回

创建多个相同的Symbol

如果在开发中我们需要创建多个相同的Symbol,那么我们可以使用Symbol.for这个方法。

let s9 = Symbol.for("12");
let s10 = Symbol.for("12");
console.log(s9 === s10); // true

Symbol的常用场景

作为属性名使用

在对象中,我们可能需要一个表示独一无二的变量,这个时候就可以用到Symbol。

实例:

// 第一种写法
var oop = {};
let s13 = Symbol('key');
oop[s13] = '海绵宝宝';
// 第二种写法
var oop1 = { [s13]: '海绵宝宝' };
// 第三种写法
var a = {};
Object.defineProperty(a, mySymbol, { value: '海绵宝宝' });

这个时候对象里面的该属性就是独一无二的。

作为独一无二的变量

有的时候我们并不需要知道这个变量里面存的值是什么,我们只想将这几个变量区分开来,保证他们是独一无二的。这个时候也可以将Symbol派上用场。

其他一些使用场景

  • 私有属性和方法:在类的实现中,可以使用Symbol来定义私有属性和方法,这样可以避免与其他属性和方法的命名冲突。

  • 迭代器:Symbol可以作为迭代器的方法名,用于迭代对象中的值。

  • 定义常量:Symbol定义的常量是唯一的,可以用作枚举类型。

  • 事件名称:在发布/订阅模式中,可以使用Symbol来定义事件名称,确保事件的唯一性。

  • 用作标记:Symbol可以用作标记,用于区分不同的代码块或函数。