【问题标题】:Is it possible to extract contents of a symbol? [duplicate]是否可以提取符号的内容? [复制]
【发布时间】:2017-04-11 16:44:34
【问题描述】:

我想制作一个将字符串映射到符号的字典,以便我可以为对象分配一个唯一的“t”属性,该属性始终指向一个唯一的符号。

我不知道如何从符号中取出符号内的原始字符串,以便查找符号表以检查符号的有效性。

示例代码如下:

var t = {
    'Box': Symbol("Box")
};

var Box = (function() {
    var Box = function(x) {
        this.t = t['Box'];
        this.x = x;
    };

    return Box;
})();

var q = new Box(2);
console.log(q);
console.log(q.t);

我想知道是否可以在不使用正则表达式或创建包含字符串“Box”和符号“Box”的新结构的情况下从符号 Symbol(Box) 中取出字符串“Box” (这可能是最好的第二种解决方案)。

【问题讨论】:

  • 以便我可以查找符号表以检查符号的有效性”是什么意思,为什么需要符号的描述?符号的全部意义不是使用字符串比较,而是依赖符号的标识。
  • 假设我使用符号识别对象;我不能使用 Symbol 作为我的字典的键。即使我知道 foo.t 是 Symbol(Box),我也无法检查它是来自表 1、表 2、表 3 还是来自碰巧有 Box 的外部脚本中的某个表中的 Symbol(Box)。为了解决这个问题,我需要获取符号字符串,并通过查找“框”并给我符号(框)的字符串来查找我的特定符号表,我可以将此符号与此特定符号(框)进行比较.
  • 当然,您可以使用符号作为字典的键——属性键不必是字符串,它们也可以是符号。或者,您可以为您的表使用数组、集合或映射。正如我所说,使用字符串进行查找会破坏符号的全部用途,您可以立即将字符串存储在.t 中。如果两个模块使用相同的符号描述,它们就会发生冲突。

标签: javascript symbols


【解决方案1】:

您不需要使用正则表达式。一个简单的slice 就可以了:

console.log(Symbol("Box").toString().slice(7, -1)); // "Box"

这必须符合规范:

19.4.3.2 Symbol.prototype.toString ( )

  1. s 成为 this 值。
  2. 如果Type(s) 是Symbol,让syms

  3. 返回SymbolDescriptiveString(sym)。

19.4.3.2.1 Runtime Semantics: SymbolDescriptiveString ( sym )

  1. descsym 的 [[Description]] 值。
  2. 如果 descundefined,则让 desc 为空字符串。

  3. 返回连接字符串"Symbol("desc")"的结果。

【讨论】:

  • 它仍然依赖于符号的特定字符串化格式;当我说正则表达式时,我暗指任何形式的字符串操作。很高兴知道 JS 支持类似 perl 的负切片来进行右偏移。
  • @Dmitry 它依赖于规范强制执行的字符串化。该规范没有提供任何其他方式来阅读 [[Description]]。
【解决方案2】:

您应该在Symbol 原语中使用forkeyFor 成员 如果您将一个字符串传递给for 方法,它会在全局注册表中搜索该字符串,如果它发现该字符串已被注册,它会检索该字符串的值,否则它会注册该字符串 keyFor 检索符号的值。将无效参数传递给 keyFor 将引发错误 >> Symbol.keyFor(arg) ,arg 必须是符号 例如

'use strict';
let myName = Symbol.for('victory');
console.log(Symbol.keyFor(myName));  // 'victory'

您的解决方案

var t = {
 'Box': Symbol.for("Box")
};

var Box = (function() {
  var Box = function(x) {
     this.t = t['Box'];
     this.x = x;
 };

  return Box;
})();

var q = new Box(2);
console.log(q);
console.log(Symbol.keyFor(q.t));

【讨论】:

  • 等等,Symbol.for 创建了一个全局符号,Symbol.keyFor 找到了全局符号,但是它们都与 Symbol('blah') 不匹配......这是否比创建您自己的表映射字符串到字符串,符号对?因为我想避免使用全局符号,因为将来我可能想在另一个上下文中使用它们,例如多个符号表,但一个表中的一个符号不等于另一个表中的符号。
  • @Dmitry Symbol.for 只是在 GlobalSymbolRegistry 中存储一个符号。我不认为这比实现自己的注册表更有效。
  • 一开始总是空的吗?有没有办法遍历全局符号注册表?
  • @Dmitry 是的,GlobalSymbolRegistry 一开始是空的。请注意,它由所有领域共享。它只能通过forkeyFor 获得。
猜你喜欢
  • 2021-09-02
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多