ES6 — Symbol

1、概述

  ES5 的对象属性名都是字符串,这容易造成属性名的冲突。于是,ES6 引入 了一种新的原始数据类型 Symbol 来保证每个属性的名字是独一无二的,从而解决了属性名冲突问题。
  ES6 引入 Symbol 后 JavaScript 就有了七种数据类型:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)、Symbol 。
  Symbol 值是通过 Symbol 函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种是新增的 Symbol 类型。
  Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述。

var s = Symbol();
typeof s => Symbol
var s1 = Symbol('foo');
s1 => Symbol(foo)

注意:
  (1)Symbol 函数前不能使用 new 命令,否则会报错。这是因为 Symbol 是一个原始数据类型,不是对象。
  (2)如果 Symbol 的参数是一个对象,就会调用该对象的 toString 方法,将其转为字符串,然后生成一个 Symbol 值。默认的 toString 方法返回的是 [Object Object]
  (3)Symbol 函数的参数只是表示当前 Symbol 值的描述,因此相同参数的 Symbol 函数返回值是不相等的。

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

  (4)Symbol 值不能与其他类型的值进行运算,会报错。
  (5)Symbol 值可以显示转为字符串。Symbol 值也可以转为布尔值(不管 Symbol 实例是否有描述,都返回 true ),但是不能转为数值。

var s3 = Symbol('3');
String(s3); => Symbol(3)
s3.toString(); => Symbol(3)
Boolean(s3); => true
!s3; -=> false
Number(s3); => 报错
s3 + 2; => 报错,不能与其他类型值进行运算

2、作为属性名的 Symbol

  由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,就能保证不会出现同名属性。

var mySymbol = Symbol();
--------------------------------------
var a = {};
a[mySymbol] = 'Hello';
--------------------------------------
var a ={
    [mySymbol]: 'Hello' 
};
--------------------------------------
var a = {};
Object.defineProperty(a, mySymbol, {value: 'Hello'});
--------------------------------------
a[mySymbol] => 'Hello'

注意:Symbol 值作为对象属性名时,不能用点运算符,因为点运算符后面总是字符串。同理,在对象内部,使用 Symbol 值定义属性时,Symbol 值必须放在方括号内。

3、Symbol 属性名的遍历

  Symbol 作为属性名,该属性不会出现在 for...infor...of 循环中,也不会被 Object.keys()Object.getOwnPropertyNames()JSON.stringify() 返回。但是,它也不是私有属性,有一个 Object.getOwnPropertySymbol 方法,可以获取指定对象的所有 Symbol 属性名。
  另一个新的 API,Reflect.ownKeys 方法可以返回所有类型的健名,包括常规健名和 Symbol 健名。
  由于 Symbol 值作为属性名,不会被常规方法遍历到,可以借助该特性为对象定义一些非私有属性,但又希望只有用于内部的方法。

4、Symbol.for() Symbol.keyFor()

  Symbol.for() 方法接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
注意:Symbol.for()Symbol() 都会返回新生成的 Symbol。区别在于,前者会被登记在全局环境中供搜索,后者不会。Symbol.for() 为 Symbol 值登记的名字,是全局环境的。

var s1 = Symbol('foo');
var s2 = Symbol('foo');
var s3 = Symbol.for('foo');
var s4 = Symbol.for('foo');
s1 === s2 => false
s3 === s4 => true
s1 === s3 => false 

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

阮一峰:ECMAScript 6入门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值