javascript ECMAScript 6中符号的用途是啥? [复制]
Posted
技术标签:
【中文标题】javascript ECMAScript 6中符号的用途是啥? [复制]【英文标题】:What is the use of Symbol in javascript ECMAScript 6? [duplicate]javascript ECMAScript 6中符号的用途是什么? [复制] 【发布时间】:2018-09-11 22:43:34 【问题描述】:Symbol在javascript(ECMASCRIPT6)中有什么用?
为什么下面的例子返回false?
常量符号 1 = 符号(); console.log(Symbol('foo') === Symbol('foo')); // 预期输出:假【问题讨论】:
MDN docs 非常清楚:“从 Symbol() 返回的每个符号值都是唯一的。” @Bergi 大声笑,很好的发现,我现在不知道我在这里回答什么并收集数据以回答这个问题,而没有注意到它已经回答了。该问题可能应该有一个更容易找到的标题(编辑了该问题的标题) @nicael 您仍然可以在此处删除您的(好!)答案并将其重新发布给更多的受众 @Bergi 完成了,感谢您的建议。 【参考方案1】:符号的想法是在Javascript中引入私有属性。但是,它的实际目的是名称冲突。
不幸的是,它们最终被严重降级,而且毕竟不是私有的,因为您可以通过反射找到它们。具体来说,通过 Object.getOwnPropertySymbols 方法和代理。
从 Symbol() 返回的每个符号值都是唯一的。符号值可以用作对象属性的标识符;这是数据类型的唯一用途。 (根据 Mozilla)
var Pet = (function()
var typeSymbol = Symbol('type');
function Pet(type)
this[typeSymbol] = type;
Pet.prototype.getType = function()
return this[typeSymbol];
return Pet;
());
var a = new Pet('dog');
console.log(a.getType()); // prints dog
a[Object.getOwnPropertySymbols(a)[0]] = "cat"
console.log(a.getType()); //prints cat
【讨论】:
这是一个可能的用例,但我不认为这是驱动力。它更多地用于处理相互覆盖的不同代码源。【参考方案2】:Symbol
用于创建一个完全唯一的、独一无二的标识符。它的用途正是您列出的示例。
即使您使用相同的字符串调用Symbol
,实例也会有所不同。这允许不同的库(可以同时使用)定义可以同时使用的键。
例如,假设两个库使用一个通用名称在 window
或 global
上定义一些东西(或者为了说明,假的全局 door
):
const door = ;
// from library 1
door.cake = () => console.log('chocolate');
// from library 2
door.cake = () => console.log('vanilla');
// your code
door.cake();
在此示例中,第一个库代码丢失了,因为它被无意地赋予了与第一个相同的名称。
现在,如果它们都使用Symbol
,那么即使它们的名称相同,您仍然可以访问它们(假设它们以某种方式导出Symbol
):
const door = ;
// library 1
const cake1 = Symbol('cake');
door[cake1] = () => console.log('chocolate');
// library 2
const cake2 = Symbol('cake');
door[cake2] = () => console.log('vanilla');
// your code
door[cake1]();
door[cake2]();
两者仍然可以访问。
这有点过于简单化了,但它说明了这一点。
在更实际的用法中,这些用于诸如导入模块之类的事情。这些模块最终可能具有相同的名称,但这没关系,因为它们将具有与之关联的唯一符号,这使得它们可以唯一地访问,只要您有 Symbol
对象。
至于何时自己使用它们......这可能会非常罕见。当您有办法提供Symbol
但需要其他东西来保持独特性时,您主要想使用它们。我只在一些狭窄的环境中直接使用了这些,其中创建的元素最终可能相同。
例如,如果您使用名称作为键来创建对象,则可能有重复的名称。如果没有符号,对象将相互覆盖。有了符号,它们都会保留下来。
const people = ;
people[Symbol('bob')] = name: 'Bob Smith' ;
people[Symbol('bob')] = name: 'Bob Jones' ;
【讨论】:
我曾尝试在***.com/questions/59768559/… 提出问题,但被告知与此重复。使您的代码运行的唯一原因是因为cake1
和 cake2
具有不同的名称,但这些名称已由开发人员指定。 Symbol
在这种情况下有何帮助?如果您将cake1
和cake2
重命名为cake
,则会收到错误消息,因为它们不是唯一的。如果Symbol
应该缓解独特的问题,它似乎在这里没有帮助。
您正在获取用作与变量名称混淆的键的值。如果您使用 let 或 const,则不能(也不应该)在同一范围内重新声明相同的变量名。不过,这与 Symbol 无关。 Symbol 是为了确保每次调用Symbol
时,无论如何都会获得一个完全唯一的标识符。我设置的“相同”的东西是Symbol('cake')
,即使我创建了两个具有相同名称的符号(或可能称为参数的“描述”),它也会生成两个唯一的符号。当您将它们用作对象中的键时,它们指的是两种不同的事物。【参考方案3】:
来自the documentation:
从
Symbol()
返回的每个符号值都是唯一的。
这意味着===
比较将失败,因为它们相同。
如果您想要一个可以给出描述性的某种唯一标识符,如果其他名称不相关,那么 Symbol 可能会很有用。
【讨论】:
好,但是在javascript中有什么用以及什么时候需要Symbol, 这可以用在你需要像 UUID 这样的唯一标识符但不关心实现细节和内容的地方。以上是关于javascript ECMAScript 6中符号的用途是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
Javascript ES6 特性概述(即ECMAScript 6和ES2015+)