Сегодня я заметил, что 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()и вы поймете, что я имею в виду