为啥隐式符号到字符串的转换会导致 JavaScript 中的 TypeError?
Posted
技术标签:
【中文标题】为啥隐式符号到字符串的转换会导致 JavaScript 中的 TypeError?【英文标题】:Why does implicit Symbol to String conversion' lead to TypeError in JavaScript?为什么隐式符号到字符串的转换会导致 JavaScript 中的 TypeError? 【发布时间】:2017-04-18 02:06:45 【问题描述】:在 ES6 中 Symbol
上有一个 .toString()
,它返回 Symbol
的字符串表示形式,但想知道为什么 '' + Symbol()
不起作用(运行此表达式会抛出我没想到的 TypeError
)?后者是否只是在新的Symbol
上调用.toString()
并将其附加(+
)到空字符串?
【问题讨论】:
@Dai'' + 123
可以作为隐式类型转换,但为什么'' + Symbol()
甚至不能被视为隐式转换?
对不起,我看错了你的问题。您实际看到的是什么行为?你有TypeError
或其他的吗?
@Dai,很抱歉这个问题引起了混乱。稍作修改。我看到'' + Symbol()
抛出 TypeError,想知道为什么会这样,因为Symbol().toString()
有效。
当我尝试 Symbol().__proto__.toString() 时它会抛出一个错误,也许它可以帮助理解这一点......(我不知道答案......)
相关:esdiscuss.org/topic/string-symbol
【参考方案1】:
后者是否只是在新的
Symbol
上调用.toString()
并将其附加(+
)到空字符串?
实际上不,符号不能隐式转换为字符串或数字,但有趣的是,您可以将它们隐式转换为布尔值。
MDN actually has a section 关于其中一些陷阱:
符号类型转换
处理符号类型转换时的一些注意事项。
尝试将符号转换为数字时,将抛出TypeError
(例如+sym
或sym | 0
)。 当使用松散相等时,Object(sym) == sym
返回true.
Symbol("foo") + "bar"
抛出TypeError
(无法将符号转换为字符串)。例如,这可以防止您从符号静默创建新的字符串属性名称。 “更安全”的String(sym)
转换类似于使用符号调用Symbol.prototype.toString()
,但请注意new String(sym)
会抛出异常。
此行为记录在 abstract ToString
operation 下的规范中:
参数类型:符号
结果:抛出
TypeError
异常。
abstract ToNumber
operation 也是如此:
参数类型:符号
结果:抛出
TypeError
异常。
要将Symbol
转换为没有TypeError
的字符串,您必须使用toString
方法或String()
。
【讨论】:
隐式将对象转换为字符串是否意味着在对象上调用Object.prototype.toString()
?
@Thomson 是的,将对象隐式转换为字符串将调用 toString
方法,如果已设置,则在实例本身上或从原型中调用。
作为您的评论,将 Symbol
隐式转换为 String
应该会成功,因为在 Symbol
实例 (Symbol()
) 上有一个可行的 toString()
?
@Thomson Symbol 实际上不是 Object 的,它们是原语,它们被明确设计为抛出 TypeError
而不是隐式调用 toString
方法。
@AlexanderO'Mara,他在问当您执行 symbol.toString() 时是否会发生意外的装箱? 或者您应该使用 String(symbol) 来防止装箱吗?跨度>
【参考方案2】:
来自https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Symbol/toString。
Symbol 对象覆盖了 Object 对象的 toString 方法; 它不继承 Object.prototype.toString()。对于符号对象, toString 方法返回对象的字符串表示形式。
【讨论】:
这不能回答问题,这就是为什么'' + symbol
不起作用。以上是关于为啥隐式符号到字符串的转换会导致 JavaScript 中的 TypeError?的主要内容,如果未能解决你的问题,请参考以下文章
符号:隐式字符串转换在 JavaScript 中是如何工作的?
重置设计 rails 的密码会导致“没有将数组隐式转换为字符串”错误