ECMAScript 6 笔记(12)- Symbol

原创 乘风逐月 随笔 ES6 117阅读 2018-09-06 15:23:41 举报

一、概述

ES5 的对象属性名都是字符串,这容易造成属性名冲突。ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型。前六种是:undefined、null、Boolean、String、Number、Object。

Symbol 值通过 Symbol 函数生成。这就是说,对象的属性名现在有两种类型,一种是字符串,一种是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就是独一无二的,可以保证不会与其他属性名冲突。

1. 基本用法

注: Symbol 函数前不能使用 new 命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象,即也不能添加属性。

Symbol 函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时比较容易区分。

不加参数,打印出来都是 "Symbol()" ,不利于区分,加上参数,等于有了描述,输出的时候就可以区分是哪一个的值。

2.注意问题

(1)Symbol 函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的 Symbol 函数的返回值是不相等。

(2)Symbol 值不能与其他类型的值进行运算,会报错。

(3)Symbol 值可以转为布尔值,但不能转为数值。

二、作为属性名的 Symbol

由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,对于对象的属性名,就能保证不会出现同名的属性。
这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。

注意:
(1)Symbol 值作为属性名时,不能用点运算符。

上例中,因为点运算后面总是字符串,所有不会读取到 'hello' ,而是 undefined。
(2)在对象内部,用 Symbol 值定义属性时,Symbol 值必须放在方括号之中。如果不放在方括号中,该属性名就是字符串,而不知 Symbol 值。
(3)Symbol 值作为属性名时,该属性还是公开属性,不是私有属性。

Symbol 类型还可以用于定义一组常量,保证这组常量的值都是不相等的。
常量使用 Symbol 值对打的好处,就是其他任何值都不可能有相同的值了。

三、属性名的遍历

Symbol 作为属性名,该属性不会出现在 for...in、for...of循环中,也不会被 Object.keys()、Object.getOwnPropertyName、JSON.stringify()返回。但是它不是私有属性。

Object.getOwnPropertySymbols() 方法,可以获取指定对象的所有 Symbol 属性名。该方法返回一个数组,成员是当前对象的所有用作属性名的 Symbol 值。
Reflect.ownkeys() 方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

由于以 Symbol 值作为名称的属性,不会被常规方法遍历得到。可以利用这个特性,为对象定义一些非私有的、但又只希望内部使用的属性方法。

四、Symbol.for()、Symbol.keyFor()

1.Symbol.for()

如果希望重新使用同一个 Symbol 值,Symbol.for() 方法可以做到这一点。他接受一个字符串作为参数,然后搜索有没有以该参数作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,如果没有就新建并返回以该字符串为名称的 Symbol 值。

Symbol.for() 与 Symbol() 的区别:
两个方法都会生成新的 Symbol。但是 Symbol.for() 不会每次都会生成新值,而是先检查给定的 key 是否存在,如果不存在才会新建一个值。但是 Symbol() 每次都会新建一个值,没有登记机制。

注: Symbol.for() 为 Symbol 值登记的名字,是全局环境的,可以在不同的 iframe 或 service worker 中取到同一个值。

2. Symbol.keyFor()

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

上例中 s1 属于未登记的 Symbol 值,所以返回 undefined。

五、内置的 Symbol 值

除了定义自己使用的 Symbol 值以外,ES6 还提供了11个内置的 Symbol 值,指向语言内部使用的方法。

// 这点等看了 class 部分来回来补上

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复