Сегодня я заметил, что Chrome 49 больше не выводит NaN
при вводе {}+{}
в консоли. Вместо этого он выводит строку [object Object][object Object]
.
Почему это? Язык изменился?
Сегодня я заметил, что Chrome 49 больше не выводит NaN
при вводе {}+{}
в консоли. Вместо этого он выводит строку [object Object][object Object]
.
Почему это? Язык изменился?
Ответы:
Chrome devtools теперь автоматически оборачивает все, что начинается {
и заканчивается }
в неявной паре скобок ( см. Код ), чтобы заставить его вычислять как выражение. Таким образом, сейчас {}
создается пустой объект. Это можно увидеть, если вернуться к истории ( ↑), в которой будет содержаться предыдущая строка (…)
.
Зачем? Я не знаю, но я мог бы предположить, что это уменьшает путаницу для новичков, которые не знают о блоке vs-object-literal, и это также более полезно, если вы просто хотите оценить выражение.
И на самом деле это рассуждение, как обсуждалось в баге 499864 . Чистое удобство. И потому что узел REPL имел это также ( см. Код ).
{a:1}),({b:2}
должен выдавать ошибку, а не выдавать объект.
)
если она есть в комментарии, например, {a:3} // :-}
все еще может появиться объект.
Если вы нажмете стрелку вверх после проверки этого, вы заметите, что вместо {} + {}
этого отображается ({} + {})
, что приводит к "[object Object][object Object]"
.
Для сравнения, в Firefox по- {} + {}
прежнему отображается NaN
, но если вы делаете ({} + {})
это, также отображается "[object Object][object Object]"
.
Итак, похоже, что Chrome автоматически добавляет окружающие скобки, когда видит эту операцию.
{} + {}
когда не "очищено", ({} + {})
обрабатывается как, + {}
потому что {}
анализируется как пустой блок.
{}
будет просто пустым блоком кода и будет игнорироваться, оставляя нас с +{}
, который является унарным +
и пустым объектом инициализатор. +
будет принуждать свой аргумент на номер, который включает в себя преобразование объекта в примитив (который будет в конечном итоге быть toString
в этом случае, в результате "[object Object]"
), и таким образом мы получаем +"[object Object]"
что , NaN
потому что "[object Object]"
не может быть преобразовано в действительное число.
К сожалению, я добавил цитату Clippy самостоятельно. Консоль не дает никакой информации о том, что она для вас сделала.
Новые правила невероятно просты, избавляя нас от необходимости кропотливо набирать эти 2 сложные символы o=
или 0,
перед вставкой литералов объектов в консоль:
{
;{wat:1}),({wat:2}
Наконец-то снова ошибка.
{let i=0;var increment=_=>i++}
наконец, правильно разрешено, что является довольно хорошим способом сделать замыкания.
Тем не менее, следующее - неправильно объект, это как удобство, как упомянуто @Bergi, он неправильно интерпретирует JS, чтобы помочь вам! Спецификация говорит, что это блок с помеченным оператором "foo" с литералом 1, который никому не назначен.
{foo:1}
Выше должно быть так же, как
if(1) {
foo: 1
}
Следующее корректно обрабатывается как блок ... потому что перед ним есть комментарий!
//magic comment
{foo:1}
Так что это:
{foo:1}
//also magic
Это объект:
{foo:
//not so magic comment
1}
Это ошибка
//not so magic comment
{foo:1}.foo
Так что это:
{foo:1}.foo
Это отлично:
1..wat
undefined
так это
['foo'][0]
Следующий корректно интерпретируется как объект, помещенный в позицию выражения с помощью a, 0,
что, как правило, позволяет нам однозначно убедиться, что у нас есть выражение вместо оператора.
0,{foo:1}.foo
Я не понимаю, почему они оборачивают ценность в паранах. У JS есть несколько нелепых дизайнерских решений, но пытаться заставить его вести себя лучше в этой ситуации, на самом деле не вариант, консоль должна правильно запускать JS, и мы должны быть уверены, что Chrome не просто догадывается, что он думает, что мы действительно хотел сделать что-то еще.
Если вам не нравятся запятые операторы, вы можете использовать присваивание
x = {foo:1}.foo
Потому что так оно и есть
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Сумасшедшим и последовательным я могу справиться ... сумасшедшим и непоследовательным, нет, спасибо!
{foo:1}
и {foo:1}//
производят тоже самое. В Chrome JS REPL их нет. REPL делает больше, чем просто оценивает JS. Он обрабатывает строки и решает разные вещи.
var x = eval('{a:1}')
В действительном JavaScript х теперь равен 1, а не более интуитивному объекту {a: 1}. Да, это странно, но вы не можете просто сменить язык, потому что он делает странные вещи. Все, кроме строк JSON, интерпретируется как JavaScript и оценивается. Печатать 0,
перед вставкой JSON не сложно, в противном случае я был бы рад предупреждению о том, что строка была интерпретирована как объект вместо JavaScript для удобства.
var e = {}; e.toString()
и вы поймете, что я имею в виду