Подтвердить что ты не робот

Что JavaScript интерпретирует `+ + i` как?

Интересная вещь, которую я никогда раньше не видел, была опубликована в другом вопросе. У них было что-то вроде:

var i = + +1;

Они думали, что дополнительный + преобразовал его в строку, но они просто добавляли строку, которая заставляла ее конвертировать.

Это, однако, привело меня к вопросу: что здесь происходит?

Я бы на самом деле ожидал, что это ошибка компилятора, но JavaScript (по крайней мере, в Chrome) с ним просто отлично... он просто ничего не делает.

Я создал небольшой JSFiddle, чтобы продемонстрировать: Демо

var i = 5;
var j = + +i;
document.body.innerHTML = i === j ? 'Same' : 'Different';
4b9b3361

Ответ 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);