Что JavaScript интерпретирует `+ + i` как?
Интересная вещь, которую я никогда раньше не видел, была опубликована в другом вопросе. У них было что-то вроде:
var i = + +1;
Они думали, что дополнительный +
преобразовал его в строку, но они просто добавляли строку, которая заставляла ее конвертировать.
Это, однако, привело меня к вопросу: что здесь происходит?
Я бы на самом деле ожидал, что это ошибка компилятора, но JavaScript (по крайней мере, в Chrome) с ним просто отлично... он просто ничего не делает.
Я создал небольшой JSFiddle, чтобы продемонстрировать: Демо
var i = 5;
var j = + +i;
document.body.innerHTML = i === j ? 'Same' : 'Different';
Ответы
Ответ 1
Полагая ваше утверждение через AST Explorer, мы можем видеть, что здесь мы получаем два вложенных выражения Unary с оператором унарного +.
Это унарное выражение, состоящее из +
и +i
, а +i
само является унарным выражением, состоящим из +
и i
.
Унарное выражение с оператором унарного + преобразует часть выражения в число. Таким образом, вы по существу конвертируете i
в число, а затем снова преобразуете результат этого числа в число (это не операция).
Для достижения цели он работает на столько уровней, сколько вы добавляете:
var i = 5;
console.log(+ + + + + +i); // 5
console.log(i); // still 5
Ответ 2
В спецификации.
Копаясь, мы можем видеть из §14.6.2.2, что операторы приращения и декремента перечислены раньше (и должны быть предпочтительными) над унарными операторами. Поэтому приоритет не объяснит это.
Поднимая таблицу препинания в §11.7, мы видим, что каждый экземпляр ++
(оператор) в спецификации показывает эти два вместе, без пробелов. Это не окончательно, пока вы не проверите...
Правила пробелов в §11.2, в частности:
Внутри StringLiteral могут появляться точки белого пространства, RegularExpressionLiteral, Template или TemplateSubstitutionTail, где они считаются значимыми кодовыми точками, составляющими часть литерального значения. Они также могут встречаться в комментарии, но не могут появляться в любом другом тике.
JS не разрешает произвольный средний оператор пробела.
Синтаксис JS как в PegJS, так и Esprima подтверждает это, сопоставляя на буквальном двухсимвольная строка ++
.
Ответ 3
Для меня это очень ясно;
var a = +3;
var b = +a; // same as a, could be -a, for instance
var c = + +a; // same as above, same as +(+a)
Ответ 4
Если вы выполняете ++variable
, интерпретатор javascript видит в нем приращение оператора.
Если вы выполняете + +variable
, интерпретатор javascript видит его как Unary plus, дважды увеличивая значение до числа.
So
var a = 1;
var b = +a;
var c = +b;
console.log(c);// still 1
совпадает с
var c = + +1;
Итак, простой ответ заключается в том, что два плюсовых знака не могут быть разделены пробелом, которое следует интерпретировать как инкремент, пространство делает так, что интерпретатор видит два отдельных пространства, что и есть на самом деле
Ответ 5
Операторы + преобразуются в число, два оператора + с пространством между ними ничего не делают.
Ответ 6
Несмотря на то, что он может выглядеть очень похожим, + +
и ++
вовсе не то же самое для интерпретатора AST. То же самое относится к разделению токенов: varfoo
не совпадает с var foo
.
В выражении + + +i
каждый x
рассматривается как отдельный унарный оператор, который просто преобразует вашу переменную в число. Для операции инкремента, которая является ++
, пробелы не допускаются ни между маркером +, ни с переменной. В приведенном ниже примере последняя строка недействительна:
var x = "4";
console.log(+ + +x);
console.log(+ + ++x);
console.log(+ ++ +x);