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 【问题描述】:

Symboljavascript(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,实例也会有所不同。这允许不同的库(可以同时使用)定义可以同时使用的键。

例如,假设两个库使用一个通用名称在 windowglobal 上定义一些东西(或者为了说明,假的全局 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/… 提出问题,但被告知与此重复。使您的代码运行的唯一原因是因为 cake1cake2 具有不同的名称,但这些名称已由开发人员指定。 Symbol 在这种情况下有何帮助?如果您将cake1cake2 重命名为cake,则会收到错误消息,因为它们不是唯一的。如果Symbol 应该缓解独特的问题,它似乎在这里没有帮助。 您正在获取用作与变量名称混淆的键的值。如果您使用 let 或 const,则不能(也不应该)在同一范围内重新声明相同的变量名。不过,这与 Symbol 无关。 Symbol 是为了确保每次调用Symbol 时,无论如何都会获得一个完全唯一的标识符。我设置的“相同”的东西是Symbol('cake'),即使我创建了两个具有相同名称的符号(或可能称为参数的“描述”),它也会生成两个唯一的符号。当您将它们用作对象中的键时,它们指的是两种不同的事物。【参考方案3】:

来自the documentation:

Symbol() 返回的每个符号值都是唯一的。

这意味着=== 比较将失败,因为它们相同

如果您想要一个可以给出描述性的某种唯一标识符,如果其他名称不相关,那么 Symbol 可能会很有用。

【讨论】:

好,但是在javascript中有什么用以及什么时候需要Symbol, 这可以用在你需要像 UUID 这样的唯一标识符但不关心实现细节和内容的地方。

以上是关于javascript ECMAScript 6中符号的用途是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

javascript 01. ECMAScript 6

学习教程| 一 ECMAScript 6 简介

《01》ECMAScript 6 简介

Javascript ES6 特性概述(即ECMAScript 6和ES2015+)

javascript ECMAScript 6中符号的用途是啥? [复制]

JavaScript ES6功能概述(ECMAScript 6和ES2015 +)