文章目录
ECMA2019资料
引入Symbol类型的背景
-
ES5 的对象属性名都是字符串,这容易造成属性名冲突的问题
举例: 使用别人的模块/对象, 又想为之添加新的属性,这就容易使得新属性名与原有属性名冲突
Symbol类型简介
-
Symbol是一种原始数据类型
- 其余原始类型: undefined 、 null 、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)
- Symbol表示独一无二的值
- Symbol类型的"真实值"无法获取,也就是说Symbol类型没有对应的字面量
- Symbol类型的意义在于区分彼此和不重复,不在于真实值
Symbol特性(所有数据类型都需要探讨的问题)
创建
- Symbol值只能通过Symbol()函数生成
let s1 s1 = = Symbol Symbol( ('foo' 'foo') ); ;
let let s2 s2 = = Symbol Symbol( ('bar' 'bar') ); ;
s1 s1 // Symbol(foo) // Symbol(foo)
s2 s2 // Symbol(bar) // Symbol(bar)
s1 s1. .toString toString( () ) // "Symbol(foo)" // "Symbol(foo)"
s2 s2. .toString toString( () ) // "Symbol(bar)"
- Symbol()函数前不能使用new命令(Symbol类型是原始值,不是对象)
- Symbol类型不能添加属性(不是对象)
- Symbol类型是一种类似字符串的类型(可用作属性名
ECMA2019标准相关:
解读: (NewTarget是使用new命令调用函数时会创建的原生对象)
(1) 如果NewTarget不为undefined
(也就是使用了new命令), 抛出错误==>Symbol函数前不能使用new
(2) 描述字符串description保存在symbol值内部的[[Description]]中
Symbol值的描述
-
Symbol 函数可以接受一个字符串作为参数
-
Symbol 函数的参数只是表示对当前 Symbol 值的描述
-
Symbol值的描述: 帮助开发者区分Symbol值
- 在控制台打印两Symbol值时,能区分开来
- 转为字符串时,能区分开来
Symbol值的类型转换与运算
类型转换
根据ECMA2019,:
- 类型转换是用一些抽象操作来描述的
- 隐式转换是直接调用某一个抽象操作
- 显示转换是抽象操作的包装(加入判断和控制等)
- 类型的构造函数 当做 函数使用(例如:
String()
) - 一些可能调用抽象操作的方法(例如:
toString()
或valueOf()
)
- 类型的构造函数 当做 函数使用(例如:
主要的类型转换抽象操作:
1.对象转原始类型:
2.转Boolean:
3.转Number:
4.转字符串:
5.原始类型转对象:
如上图, 直接对symbol值应用抽象操作(隐式转换):
- ToBoolean(Symbol)==>true
- ToString(Symbol)==>报错
- ToNumber==>报错
类型转换举例
let sym = Symbol('My symbol');
"your symbol is" + sym; //TypeError: can't convert symbol to string
`your symbol is ${
sym}`; //TypeError: can't convert
String(sym); //'Symbol(My symbol)'
sym.toString(); //'Symbol(My symbol)'
为什么上述代码中String()和sym.toString()可以成功将symbol转换为字符串?
ECMA2019:
(1)Symbol作为原始类型, 有对应的包装对象类型, 所以我们可以用sym.toString()
调用方法而不出错.
更进一步,我们测试一下Symbol类型的实例是否可改变和添加属性:
let s = Symbol('s');
//实例对象的对象保护检测
console.log(`s实例是否可扩展: ${
Object.isExtensible(s)}`);
console.log(`s实例是否被冻结: ${
Object.isFrozen(s)}`);
console.log(`s实例是否被封闭: ${
Object.isSealed(s)}`);
//输出:
// s实例是否可扩展: false
// s实例是否被冻结: true
// s实例是否被seal: true
//实例对象是否存在toString实例方法与[[Symbol.toStringTag]]
console.