我遇到了一个案例,其中 Javascript 字符串插值没有给出与字符串连接相同的结果。
这是显示差异的代码的简化版本:
const mmt = moment();
console.log('concatenated: ' + mmt); // "concatenated: 1651070909974"
console.log(`interpolated: ${mmt}`); // "interpolated: Wed Apr 27 2022 10:48:29 GMT-0400"
console.log('mmt.valueOf(): ' + mmt.valueOf()); // "mmt.valueOf(): 1651070909974"
console.log('mmt.toString(): ' + mmt.toString()); // "mmt.toString(): Wed Apr 27 2022 10:48:29 GMT-0400"
所以我的直接想法是,这是由于 .toString()
的差异造成的。和 .valueOf()
,所以我做了一个小测试对象来验证:const obj = {
toString: () => 'toString',
valueOf: () => 'valueOf',
};
console.log('concatenated: ' + obj); // "concatenated: valueOf"
console.log(`interpolated: ${obj}`); // "interpolated: toString"
console.log('obj.valueOf(): ' + obj.valueOf()); // "obj.valueOf(): valueOf"
console.log('obj.toString(): ' + obj.toString()); // "obj.toString(): toString"
但是,当我使用 Date 对象(与 .toString()
与 .valueOf()
的结果也不同)尝试此操作时,我没有得到相同的行为——这次插值和连接都使用 .toString()
值(value):const dte = new Date();
console.log('concatenated: ' + dte); // "concatenated: Wed Apr 27 2022 10:48:29 GMT-0400 (Eastern Daylight Time)"
console.log(`interpolated: ${dte}`); // "interpolated: Wed Apr 27 2022 10:48:29 GMT-0400 (Eastern Daylight Time)"
console.log('dte.valueOf(): ' + dte.valueOf()); // "dte.valueOf(): 1651070909974"
console.log('dte.toString(): ' + dte.toString()); // "dte.toString(): Wed Apr 27 2022 10:48:29 GMT-0400 (Eastern Daylight Time)"
所以我的问题是:在连接和插值时如何将插值转换为字符串的实际规则是什么,为什么 Date 似乎与其他对象不同? (我试图查找这个,但到目前为止我的谷歌搜索一直不成功......)JSFiddle Example
最佳答案
行为上的差异确实与 +
相关。运算符,它背后有一个特定的过程:
关于抽象操作的 ECMAScript 规范 ToPrimitive指定如果没有提供类型提示(如 the +
operator 的情况),将发生以下情况:
Symbol.toPrimitive
方法,然后它将被调用(提示“默认”)。此方法可以将调用转发到 toString
. Date
就是这种情况。对象。 valueOf
将被调用。 moment
就是这种情况。目的。 处理
+
过程复杂的原因运算符,是它还用于算术加法。这种复杂性在评估模板文字时不存在,因为总是要进行字符串连接,因此
Symbol.toPrimitive
方法将使用“字符串”提示(而不是“默认”)调用,或者如果该方法不存在,toString
将被调用。所以你的假设
+
是纯字符串连接,不是那么准确。当您使用 .concat
时,看看它的不同之处。方法:const mmt = moment();
console.log('concatenated: '.concat(mmt));
// Not same result as with +
console.log('plus operator: ' + mmt);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.3/moment.min.js"></script>
关于Javascript字符串插值给出与字符串连接不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72031214/