ES6学习笔记(12)之 Symbol

参考:ECMAScript 6 入门

Symbol

为什么要引入Symbol:

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

是什么?

它是 JavaScript 语言的第七种数据类型,表示独一无二的值,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。

生成Symbol类型的值:
重点:不能用new命令生成symbol类型的值
原因:因为生成的 Symbol 是一个原始类型的值,不是对象。(可以认为通过调用Symbol()方法返回一个symbol类型的值?通过new生成的都是对象。)

无参数形式:

let s = Symbol(); 
typeof s // "symbol"

有参数形式:

let s1 = Symbol('foo');

两种形式的比较:(关键词:描述)
本质是一样的;但有参数形式的参数是一种描述,方便debug;也可以将对象传入作为参数,这个对象也是对symbol值的描述。


非重点区:
Symbol 值不能与其他类型的值进行运算,会报错。

let sym = Symbol('My symbol');
"your symbol is " + sym
// TypeError: can't convert symbol to string

Symbol 值可以显式转为字符串(本质是因为调用了传入的参数的toString方法)

let sym = Symbol('My symbol');
String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'

Symbol 值也可以转为布尔值

let sym = Symbol();
Boolean(sym) // true
!sym  // false

作为属性名举例:

let mySymbol = Symbol();

// 第一种写法
let a = {};
a[mySymbol] = 'Hello!';

// 第二种写法
let a = {
  [mySymbol]: 'Hello!'
};

不能通过点的方式访问symbol属性的值。因为通过点形式访问的,那个属性名必须是字符串,这也解释了为什么在上面那个例子中,定义symbol属性时必须加上[]。

const mySymbol = Symbol();
const a = {};

a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"

哪种场景下用Symbol最合适?
我们只作为一个flag使用的时候,变量值取任何字符串都不影响结果的时候。

如何遍历symbol属性:
Symbol 作为属性名,不能被任何方式遍历或枚举,除了使用Object.getOwnPropertySymbols方法(其实还可以通过Reflect.ownKeys这种方式获取,此处不表)


非重点区:
Symbol.for() 与 Symbol() 的区别:

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true

讲解:当给s1赋值时,这个symbol的值会在全局环境中登记(通过foo: Symbol('foo')的形式登记),再通过Symbol.for('foo'),会根据foo去全局搜索,如果找到了,就返回原来的symbol值(感觉有点像java中字符串的定义:String a = 'symbol'; String b = 'symbol'; System.out.print(a === b); // true

Symbol()每次都会返回新的(Symbol.for() 与 Symbol() 的区别,感觉有点类似于java中String a = 'symbol'; String b = new String('symbol');的区别,不过Symbol()的值不是对象)

ES6内置symbol属性名举例:

Symbol.hasInstance
Symbol.isConcatSpreadable
Symbol.species
Symbol.match
Symbol.replace
Symbol.search
Symbol.split
Symbol.iterator
Symbol.toPrimitive
Symbol.toStringTag

你可能感兴趣的:(ES6学习笔记(12)之 Symbol)