我可以依赖 ES6 `Symbol` 的字符串表示吗?
Can I rely on the string representation of an ES6 `Symbol`?
我正在开发一个通过网络发送部分数据的 ES6 应用程序。其中一部分涉及作为 ES6 Symbol
s 实现的标识符。例如:
const FOO = Symbol('foo');
调用 Foo.toString()
产生 Symbol(foo)
。当我通过网络传递这些时,我想将其作为 foo
传递。但是,据我所知,除了使用正则表达式(具体来说,/^Symbol\((.*)\)$/
)之外,没有办法从 Symbol(foo)
中提取 foo
。
我应该依靠正则表达式始终匹配吗?或者未来对 ES6 的更新是否有可能打破这个?如果我不能依赖正则表达式匹配,那么我将通过网络将其作为 Symbol(foo)
.
发送
根据 spec 它总是 "Symbol(" + description + ")"
。
Symbol.prototype.toString
returns 来自内部方法调用的字符串 SymbolDescriptiveString(sym)
:
Let desc be sym’s [[Description]]
value.
If desc is undefined
, let desc be the empty string.
[…]
Return the string-concatenation of "Symbol("
, desc, and ")"
.
现在,在 2019 年更新此答案,您有两个选择:
使用(或 polyfill)Symbol.prototype.description
, which is part of ECMAScript 2019 并被所有现代 JavaScript 引擎支持:
const foo = Symbol("foo"),
bar = Symbol.for("bar"),
iter = Symbol.iterator;
console.log(foo.description); // "foo"
console.log(bar.description); // "bar"
console.log(Symbol.iterator.description); // "Symbol.iterator"
或者像这样使用Symbol.prototype.toString
:
const foo = Symbol("foo"),
bar = Symbol.for("bar"),
iter = Symbol.iterator;
console.log(foo.toString().slice(7, -1)); // "foo"
console.log(bar.toString().slice(7, -1)); // "bar"
console.log(iter.toString().slice(7, -1)); // "Symbol.iterator"
// Or without “magic numbers”:
console.log(foo.toString().slice("Symbol(".length, -")".length)); // "foo"
console.log(bar.toString().slice("Symbol(".length, -")".length)); // "bar"
console.log(iter.toString().slice("Symbol(".length, -")".length)); // "Symbol.iterator"
由于描述周围的字符串是固定的,slice
是一个很好的选择,特别是因为交易品种描述本身可以包含括号、换行符、字符串 "Symbol"
等,并且例如,正则表达式中的 .
不会匹配换行符。
唯一要添加到@Xufox 的答案是 Symbol.prototype.toString
可能会受到损害(覆盖),在这种情况下它可能 return 其他东西。考虑到您 want/need 几乎不会考虑这种情况,应该没问题;争取 .toString().slice(7, -1);
.
您可能要考虑的替代解决方案是使用全局符号。如果你要传递你的数据,并且无论如何都需要防止名称冲突,这将是一个合适的用例(假设你没有编写一个应该被第三方使用的库)。
你会用
const FOO = Symbol.for("foo");
// ^^^
然后可以通过
取回符号的名称(也是它的描述)
Symbol.keyFor(FOO) // "foo"
我正在开发一个通过网络发送部分数据的 ES6 应用程序。其中一部分涉及作为 ES6 Symbol
s 实现的标识符。例如:
const FOO = Symbol('foo');
调用 Foo.toString()
产生 Symbol(foo)
。当我通过网络传递这些时,我想将其作为 foo
传递。但是,据我所知,除了使用正则表达式(具体来说,/^Symbol\((.*)\)$/
)之外,没有办法从 Symbol(foo)
中提取 foo
。
我应该依靠正则表达式始终匹配吗?或者未来对 ES6 的更新是否有可能打破这个?如果我不能依赖正则表达式匹配,那么我将通过网络将其作为 Symbol(foo)
.
根据 spec 它总是 "Symbol(" + description + ")"
。
Symbol.prototype.toString
returns 来自内部方法调用的字符串 SymbolDescriptiveString(sym)
:
Let desc be sym’s
[[Description]]
value.
If desc isundefined
, let desc be the empty string.
[…]
Return the string-concatenation of"Symbol("
, desc, and")"
.
现在,在 2019 年更新此答案,您有两个选择:
使用(或 polyfill)
Symbol.prototype.description
, which is part of ECMAScript 2019 并被所有现代 JavaScript 引擎支持:const foo = Symbol("foo"), bar = Symbol.for("bar"), iter = Symbol.iterator; console.log(foo.description); // "foo" console.log(bar.description); // "bar" console.log(Symbol.iterator.description); // "Symbol.iterator"
或者像这样使用
Symbol.prototype.toString
:const foo = Symbol("foo"), bar = Symbol.for("bar"), iter = Symbol.iterator; console.log(foo.toString().slice(7, -1)); // "foo" console.log(bar.toString().slice(7, -1)); // "bar" console.log(iter.toString().slice(7, -1)); // "Symbol.iterator" // Or without “magic numbers”: console.log(foo.toString().slice("Symbol(".length, -")".length)); // "foo" console.log(bar.toString().slice("Symbol(".length, -")".length)); // "bar" console.log(iter.toString().slice("Symbol(".length, -")".length)); // "Symbol.iterator"
由于描述周围的字符串是固定的,slice
是一个很好的选择,特别是因为交易品种描述本身可以包含括号、换行符、字符串 "Symbol"
等,并且例如,正则表达式中的 .
不会匹配换行符。
唯一要添加到@Xufox 的答案是 Symbol.prototype.toString
可能会受到损害(覆盖),在这种情况下它可能 return 其他东西。考虑到您 want/need 几乎不会考虑这种情况,应该没问题;争取 .toString().slice(7, -1);
.
您可能要考虑的替代解决方案是使用全局符号。如果你要传递你的数据,并且无论如何都需要防止名称冲突,这将是一个合适的用例(假设你没有编写一个应该被第三方使用的库)。
你会用
const FOO = Symbol.for("foo");
// ^^^
然后可以通过
取回符号的名称(也是它的描述)Symbol.keyFor(FOO) // "foo"