Строка буквальная первая или вторая в конкатенации?
В JavaScript есть ли какие-либо обстоятельства, когда существует семантическая разница между этими двумя параметрами?
foo.bar + ''
...а также...
'' + foo.bar
Я бы ожидал, что последний более надежно принудит результат к строке, но я не могу найти никакого обсуждения этого (после большого Googling) и ни одного примера, где это, кажется, имеет значение.
Ответы
Ответ 1
Они такие же, как другие, о которых уже упоминалось, с дополнительными соображениями, перечисленными @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
Оба они одинаковы.
Существует только разница, если есть другие +
(слева или справа). Другими словами:
1 + 1 + '' // results in '2'
Это не то же самое, что:
'' + 1 + 1 // results in '11'
Ответ 3
Если один из операндов является строкой, на другой будет вызываться valueOf()
или toString()
, так что да, они точно такие же.
12.8.3 спецификации:
AdditiveExpression + MultiplicativeExpression
-
Пусть lref является результатом оценки AdditiveExpression.
-
Пусть lval be? ПолучитьЗначение (LRef).
-
Пусть rref является результатом вычисления мультипликативного выражения.
-
Пусть rval be? ПолучитьЗначение (RREF).
-
Пусть lprim будет? ToPrimitive (lval).
-
Пусть rprim be? ToPrimitive (RVAL).
-
Если Type (lprim) является String или Type (rprim), является String, тогда
а. Пусть lstr будет? ToString (lprim).
б. Пусть rstr? ToString (rprim).
с. Вернуть строку, которая является результатом объединения lstr и rstr
Ответ 4
Вот несколько правил, взятых отсюда
- Если хотя бы один операнд является объектом, он преобразуется в примитивное значение (строка, число или логическое значение);
- После преобразования, если хотя бы один операнд является строковым типом, второй операнд преобразуется в строку и выполняется конкатенация;
- В другом случае оба операнда преобразуются в числа и выполняется арифметическое добавление.
Ответ 5
Нет, нет никакой разницы.
Если 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);