摘要:先搜索全局符号注册表,如果已有,则返回这个已存在的符号值否则,会创建一个新的符号值,并使用该键值将其记录到全局符号注册表中,然后返回这个新的符号值。
主要知识点:创建符号值、使用符号值、共享符号值、符号值转换。检索符号值属性以及知名符号
《深入理解ES6》笔记 目录
ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
创建符号值let firstName = Symbol(); let person = {}; person[firstName] = "Nicholas"; console.log(person[firstName]); // "Nicholas" console.log(firstName ); // Symbol() typeof firstName //"symbol"
由于符号值是基本类型的值,因此调用 new Symbol() 将会抛出错误。你可以通过 new
Object(yourSymbol) 来创建一个符号实例,但尚不清楚这能有什么作用。
Symbol 函数还可以接受一个额外的参数用于描述符号值,该描述并不能用来访问对应属性,可以用于调试;
let firstName = Symbol("first name"); let person = {}; person[firstName] = "Nicholas"; console.log("first name" in person); // false console.log(person[firstName]); // "Nicholas" console.log(firstName); // "Symbol(first name)"使用符号值
可以在任意能使用“需计算属性名”的场合使用符号,还可以在Object.defineProperty() 或 Object.defineProperties() 调用中使用它:
let firstName = Symbol("first name"); // 使用一个需计算字面量属性 let person = { [firstName]: "Nicholas" }; // 让该属性变为只读 Object.defineProperty(person, firstName, { writable: false }); let lastName = Symbol("last name"); Object.defineProperties(person, { [lastName]: { value: "Zakas", writable: false } }); console.log(person[firstName]); // "Nicholas" console.log(person[lastName]); // "Zakas"共享符号值
如果需要在应用中需要在两个不同的对象类型中使用同一个符号属性,用来表示一个唯一标识符,可以使用Symbol.for()创建共享符号值;
Symbol.for()方法仅接受单个字符串类型的参数,作为目标符号值的标识符,同时此参数也会成为该符号的描述信息。
let uid = Symbol.for("uid"); let object = {}; object[uid] = "12345"; console.log(object[uid]); // "12345" console.log(uid); // "Symbol(uid)"
先搜索全局符号注册表,如果已有,则返回这个已存在的符号值;否则,会创建一个新的符号值,并使用该键值将其记录到全局符号注册表中,然后返回这个新的符号值。
let uid = Symbol.for("uid"); let object = { [uid]: "12345" }; console.log(object[uid]); // "12345" console.log(uid); // "Symbol(uid)" let uid2 = Symbol.for("uid"); console.log(uid === uid2); // true console.log(object[uid2]); // "12345" console.log(uid2); // "Symbol(uid)"
Symbol.keyFor() 方法在全局符号注册表中根据符号值检索出对应的键值:
let uid = Symbol.for("uid"); console.log(Symbol.keyFor(uid)); // "uid" let uid2 = Symbol.for("uid"); console.log(Symbol.keyFor(uid2)); // "uid" //uid3在全局注册表中并不存在,会返回undefined let uid3 = Symbol("uid"); console.log(Symbol.keyFor(uid3)); // undefined符号值的转换
类型转换是 JS 语言重要的一部分,能够非常灵活地将一种数据类型转换为另一种。然而符号类型在进行转换时非常不灵活,因为其他类型缺乏与符号值的合理等价,尤其是符号值无法被转换为字符串值或数值,在逻辑运算符中会被认为等价于 true。
let uid = Symbol.for("uid"), desc = uid + ""; // 引发错误!
// 使用console.log() 来展示符号值的输出,能这么做是由于自动调用了符号的 String() 方法来产生输出。你也可以直接调用 String() 方法来获取相同结果 let uid = Symbol.for("uid"), desc = String(uid); console.log(desc); // "Symbol(uid)"检索符号属性
Object.keys() 与 Object.getOwnPropertyNames() 方法可以检索对象的所有属性名称,但不能返回符号类型的属性,ES6 新增Object.getOwnPropertySymbols() 方法,以便让你可以检索对象的符号类型属性。
Object.getOwnPropertySymbols() 方法会返回一个数组,包含了对象自有属性名中的符号值:
let uid = Symbol.for("uid"); let object = { [uid]: "12345" }; let symbols = Object.getOwnPropertySymbols(object); console.log(symbols.length); // 1 console.log(symbols[0]); // "Symbol(uid)" console.log(object[symbols[0]]); // "12345"
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108471.html
摘要:设置对象属性只读。提供了一个注册机制,当你注册之后,就能在全局共享注册表里面的。的注册表和对象表很像,都是结构,只不过这个是值。语法只有一个参数,返回的是从注册表获取全局共享的注意如果要防止命名重复问题,可以加上前缀。 还记得对象Object吗? let obj = { a: 1 } 对象的格式: Object { key: value } 在ES5的时代,对象的key只能...
摘要:的码点被称为基本字符区域。关于的介绍,我准备用文档阮一峰来做一些介绍,具体的可以参考文档引入的原因的对象属性名都是字符串,这容易造成属性名的冲突。其他的一些属性可以去看文档阮一峰注意函数前不能使用命令,否则会报错。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完...
摘要:的码点被称为基本字符区域。关于的介绍,我准备用文档阮一峰来做一些介绍,具体的可以参考文档引入的原因的对象属性名都是字符串,这容易造成属性名的冲突。其他的一些属性可以去看文档阮一峰注意函数前不能使用命令,否则会报错。 笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完...
阅读 3122·2021-11-24 09:39
阅读 3123·2021-10-21 09:38
阅读 2380·2019-08-29 15:28
阅读 3674·2019-08-26 12:23
阅读 2595·2019-08-26 12:19
阅读 1330·2019-08-23 12:44
阅读 2091·2019-08-23 12:02
阅读 955·2019-08-22 17:05