Symbol 是一种基本数据类型,Symbol()函数会返回 是一种基本数据类型,Symbol 类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的 symbol 注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:”new Symbol()”。
每个从 Symbol()返回的 symbol 值都是唯一的。一个 symbol 值能作为对象属性的标识符;这是该数据类型仅有的目的。
基础语法
Symbol 值通过 Symbol 函数生成,使用 typeof,结果为 “symbol”
1 2 3
let s = Symbol();
typeof s;
不能使用 new 命令
因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。
1 2 3
var s1 = Symbol("foo"); console.log(s1); // Symbol(foo) s1.toString(); // "Symbol(foo)"
instanceof 的结果为 false
1 2
var s = Symbol("foo"); s instanceofSymbol; // false
如果 Symbol 的参数是一个对象,就会调用该对象的 toString 方法,将其转为字符串,然后才生成一个 Symbol 值。
1 2 3 4 5 6 7 8
var obj = { name: "lilei", toString() { returnthis.name; }, }; const s = Symbol(obj); console.log(s); // Symbol(lilei)
Symbol 作为属性名
由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
let mySymbol = Symbol();
// 第一种写法 let a = {}; a[mySymbol] = "Hello!";
// 第二种写法 let a = { [mySymbol]: "Hello!", };
// 第三种写法 let a = {}; Object.defineProperty(a, mySymbol, { value: "Hello!" });
Symbol 作为属性名,该属性不会出现在 for…in、for…of 循环中,也不会被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。 但是,它也不是私有属性,有一个 Object.getOwnPropertySymbols 方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
1 2 3 4 5 6 7 8 9 10 11
const obj = {}; let a = Symbol("a"); let b = Symbol("b");