【问题标题】:Is it possible to access the value of a Symbol in JavaScript?是否可以在 JavaScript 中访问 Symbol 的值?
【发布时间】:2020-02-17 04:06:17
【问题描述】:

我刚刚了解了 JavaScript 中符号的概念。我被告知它们可用于创建唯一标识符以避免潜在的冲突。

例如...

let user = {
    name        : "John",
    Symbol("id"): 123,    // Symbol("id") is a unique identifier
    Symbol("id"): 123     // and the Symbol("id") here is also different and unique
 };

...我理解上面的代码。但是,每个 "Symbol("id")" 的实际标识符值是多少?我怎么知道?

任何指针表示赞赏。

【问题讨论】:

  • 我不明白这个问题。符号的值是什么意思?符号只是一个有名字的对象,可以用作唯一标识符。
  • 您是在问如何从id1 转到字符串"id"
  • @Barmar 我只是询问允许我们查看唯一标识符内容的方法。目前,我被告知标识符是唯一的......但是我如何才能真正查看内容以确认?
  • console.log(id1 == id2) 会说false,所以你知道它们是不同的,即使它们都包含id
  • @Grateful 你想错了,符号本身就是一个唯一的标识符。没有可以从中提取的“内容”或“价值”。

标签: javascript symbols


【解决方案1】:

不,在 JS 环境中看不到符号的“原始”值,因为它是使用 JS 引擎本身的原生 C++ 代码实现的,并且这种实现不提供在任何地方显示它的机会在控制台或页面上。

您可以将符号视为大数字,每次创建符号时,都会生成一个新的随机数 (uuid)。您可以使用该符号(随机大数)作为对象中的键。 关于这个定义,可以看一下ES5中符号的possible implementation

var Symbol;
if (!Symbol) {
Symbol = (function(Object){

// (C) WebReflection Mit Style License

var ObjectPrototype = Object.prototype,
    defineProperty = Object.defineProperty,
    prefix = '__simbol' + Math.random() + '__',
    id = 0;

//... some other code

可以看到这里用到了Math.random(),所以Symbol里面会有long big number作为他的主要属性(唯一的可能性很大)。

另一种解释符号是什么的方式是,符号只是一块内存,您可以在其中存储一些数据。每个符号将指向不同的内存位置。在此定义的上下文中,您可以看到 JS 引擎本身的 C++ 源代码,for example V8 在 Chromium 中使用。如果你懂 C++,你可以尝试在那里找到 Symbol() 构造函数的实现,但这并不容易。

因此,我们可以说Symbol是某种字符串描述的唯一内存区域。内存区域本身已经是低级编程的术语,因此您可以将其视为类似于 1010010011...

【讨论】:

    【解决方案2】:

    来自mdn

    从 Symbol() 返回的每个符号值都是唯一的。符号值 可用作对象属性的标识符;这是数据 类型的唯一目的。

     console.log(Symbol('foo') === Symbol('foo'))
     

    来自an article in this answer

    ES6 符号类似于语言中更传统的符号 像 Lisp 和 Ruby,但没有如此紧密地集成到语言中。 在 Lisp 中,所有的标识符都是符号。在 JS 中,标识符和大多数 属性键仍被视为字符串。符号只是额外的 选项。

    正如mdn docs 解释的那样,您可以访问您传递的Description,但不能访问Symbol 的值:

    JavaScript 中的大多数值都支持隐式转换为字符串。为了 例如,我们几乎可以提醒任何值,并且它会起作用。符号是 特别的。它们不会自动转换。

    例如,

    let Sym = Symbol("Sym");
    alert(Sym); // TypeError: Cannot convert a Symbol value to a string

    这是防止搞砸的“语言守卫”,因为字符串和 符号是根本不同的,不应该偶尔 将一个转换成另一个。

    如果我们真的想显示一个符号,我们需要在它上面调用 .toString(), 例如,

     
    let Sym = Symbol("Sym");
    alert(Sym.toString()); // Symbol(Sym), now it works 

    或者我们可以使用 get symbol.description 属性来获取 例如,上面的描述,

     
    let _Sym = Symbol("Sym");
    alert(_Sym.description); // Sym 
     

    【讨论】:

      【解决方案3】:

      const id1 = Symbol("id");
      const id2 = Symbol("id");
      
      const user = {
          name: "John",
          [id1]: 123,    // "[id1]" is a unique identifier
          [id2]: 456,    // and the value of "[id2]" here is also different
      };
      
      console.log('id1:', user[id1], id1.description);
      console.log('id2:', user[id2], id2.description);

      【讨论】:

      • 感谢您帮助我。但具体来说,我不是在谈论值“123”或“456”。我说的是实际的标识符值本身。
      【解决方案4】:

      我无法正确回答您的问题,我试图帮助您希望这会奏效

      let user = { // belongs to another code
        name: "Alex"
      };
      
      let id = Symbol("id");
      
      user[id] = 200;
      
      alert( user[id] ); // we can access the data using the symbol as the key

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-01
        • 2012-10-22
        • 1970-01-01
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 2022-11-03
        相关资源
        最近更新 更多