ES12 中的 Symbol 类型的新使用:解决 “Magic Property” 的问题
前言
在前端开发中,我们经常会遇到 “Magic Property” 的问题。什么是 “Magic Property” 呢?就是一些随意设置的属性,经常会导致出现一些奇怪的行为或者 bug。这些属性往往命名不规范,甚至不一定要遵循 JavaScript 的命名规则,这就需要我们在代码维护时非常小心。在 ES12 中,Symbol 类型的新使用为解决这个问题提供了很好的解决办法。
一、Symbol 的基本概念
Symbol 是一个新的数据类型,通过 Symbol 函数生成。Symbol 函数传入的参数是一个字符串,用于描述这个 Symbol 的信息,但是并不是这个字符串成为了 Symbol 的名称,因为 Symbol 是唯一的,只要传入的参数相同,生成的 Symbol 就是相同的。
使用 Symbol() 函数创建 Symbol 类型的变量:
let s1 = Symbol(); let s2 = Symbol(); console.log(s1 === s2); // false
Symbol()
函数返回一个新的、独一无二的 Symbol 类型值,因此,无论调用多少次 Symbol()
函数,每次返回的值都是不相等的。
我们可以通过 typeof 运算符,查看 Symbol 类型:
console.log(typeof s1); // symbol
二、Symbol 的用途
1.提供对象私有属性
在 JavaScript 的对象中,属性都是公有的,我们无法将一些属性私有化,开发者可以随意修改这些属性,而在其他语言中我们可以通过修饰符的方式达到私有化属性的效果。在 ES6 之前,JavaScript 中没有私有属性的概念,但是通过 Symbol 我们可以实现对象私有属性的效果。
let obj = {}; const s3 = Symbol('key1'); obj[s3] = 'secrecy'; console.log(obj); // {} console.log(obj[s3]); // secrecy
我们可以将 Symbol 作为对象的属性名,这样,就达到了私有化属性的效果,只有知道 Symbol 值的代码才能够读取这个属性。
2.解决 "Magic Property" 的问题
Symbol()
函数创建的值是唯一的,因此,我们可以用其创建一组独一无二的属性名,并将这些属性用于对象中,从而避免 "Magic Property" 的问题。
-- -------------------- ---- ------- ----- -------- - ----------- - ----- -------- - --------- --- ------------ - --- ------ - ----------- --------- ------- ---------- ---------- - ------ ------------- -- ---- ------------- - ------------ - ---- - -- ----- ---------------------------------- -- -- ----------------- ---------------------------------- -- -- -------------------------------- -- -------- -----
在这里,我们用Symbol()
函数分别创建了 MY_CONST
量和模块 MyModule
中的所有方法名。这样做的好处是,通过 MY_CONST
,我们可以访问 MyModule
中的常量而不用担心被错误修改。如果我们用原始字符串作为属性名,就必须一遍又一遍地谨慎验证所有属性的名称,这样才能确信代码不会出现 "Magic Property" 的问题。
三、总结
不管是对象私有属性还是解决 "Magic Property" 的问题,Symbol 都有很好的运用场景。通过 symbol 创建的属性是不可修改且不会重复的,能够保持对象属性的唯一性,从而避免冲突或污染全局命名空间。在前端开发中,我们通常也需要应用 Symbol 来提升代码的质量和可维护性。
示例代码使用了模块模式展示了 Symbol 的实现逻辑,结合 ES6 的语法,在全局变量保持不变的前提下,通过对象属性名的形式配置对象的相关属性并返回,同时提供一些接口实现对对内部属性的修改,进一步加强了代码的安全性和可控性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649d4efc48841e9894a0f36d