在JavaScript中,这两个选项之间在语义上是否存在差异?
foo.bar + ''
...和...
'' + foo.bar
我希望后者能更可靠地将结果强制转换为字符串,但是我(在经过大量谷歌搜索之后)找不到任何讨论,也找不到任何看起来很重要的例子。
答案 0 :(得分:15)
两者都一样。
只有其他+
(在左侧或右侧)才有所不同。换句话说:
1 + 1 + '' // results in '2'
不同于:
'' + 1 + 1 // results in '11'
答案 1 :(得分:13)
它们与其他人已经提到的相同,并在@Zohaib Ijaz中列出了其他注意事项:
var values = [
undefined,
null,
false,
true,
0,
-1,
1,
NaN,
Infinity,
'',
'123',
'abc123',
'123abc',
[],
[0],
[1],
{},
{a: 1},
function(){}
];
var foo = {bar: null};
values.forEach(function(value) {
foo.bar = value;
console.log("foo.bar + '':", foo.bar + '');
console.log("'' + foo.bar:", '' + foo.bar);
});
但是,如果您有 2个以上的操作数(如@ibrahim mahrir所述,则存在显着差异:
var values = [
undefined,
null,
false,
true,
0,
-1,
1,
NaN,
Infinity,
'',
'123',
'abc123',
'123abc',
[],
[0],
[1],
{},
{a: 1},
function(){}
];
var foo = {bar: null};
values.forEach(function(value) {
foo.bar = value;
console.log("foo.bar + '' + foo.bar:", foo.bar + '' + foo.bar);
console.log("'' + foo.bar + '':", '' + foo.bar + '');
});
答案 2 :(得分:5)
如果一个操作数是一个字符串,则将valueOf()
或toString()
调用另一个,所以是的,它们是完全相同的。
规范的12.8.3:
AdditiveExpression + MultiplicativeExpression
让lref是评估AdditiveExpression的结果。
让lval是吗? GetValue(lref)。
让rref成为对MultiplicativeExpression求值的结果。
让rval为? GetValue(rref)。
让lprim成为? ToPrimitive(lval)。
让rprim是? ToPrimitive(rval)。
如果Type(lprim)为String或Type(rprim)为String,则然后
a。让lstr成为? ToString(lprim)。
b。让rstr为? ToString(rprim)。
c。返回将lstr和rstr串联的结果的字符串
答案 3 :(得分:3)
不,没有区别。
如果foo.bar
不是原始值,则首先调用valueOf
。如果仍然没有返回原始值,则在其上调用toString
。如果仍然没有返回原始值,则会触发错误。
在所有这一切中,foo.bar
对象不知道在哪个上下文中valueOf
或toString
被调用。对象无法区分您提到的两种情况。甚至不必是这两个之一。
最后,无法在+
运算符上设置陷阱,因此您可以知道其操作数。
以下是如何按此顺序调用valueOf
和toString
的演示:
const foo = {
bar: {
valueOf() {
console.log('valueOf');
return this; // not a primitive value, so now toString will be called.
},
toString() {
console.log('toString');
return "1";
}
}
}
console.log(foo.bar + '');
console.log("====");
console.log('' + foo.bar);
答案 4 :(得分:2)
以下是从here
摘录的一些规则