2013-07-16 2 views
1

Если вы оцениваете 1|0,2|0 на JavaScript, вы получите 2.Почему 1 | 0,2 | 0 равно 2 в JavaScript?

Если вы оцениваете 1|0+','+2|0, вы получите 1.

Я не могу понять это.

+9

[Comma Operator] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator) – Andreas

+0

то почему он возвращает 1 во втором выражении? – Isaac

+4

Эта вторая запятая является строковым литералом, а не оператором. – Quentin

ответ

11

Бинарные побитовые операторы (включая |) связывают менее плотно, чем оператор сложения +. Таким образом

1|0+','+2|0 

действительно

1|(0+','+2)|0 

который

1|('0,2')|0 

который

1|0|0 

который 1. (Строка «0,2» преобразуется в целое число,. Как числа это NaN, а потому, что NaN это понятие с плавающей точкой он превращается в 0, когда вынужден быть целым)

редактировать — относительно первого выражения, 1|0,2|0, что связано с оператором запятой JavaScript. Оператор запятой допускает, чтобы список отдельных, по существу независимых (кроме побочных эффектов) выражений «склеивался» во что-то, что парсер распознает как одно выражение. Когда оценивается, каждое выражение будет вычисляться так, как обычно, но значение общего выражения - это просто значение последнего в списке. Таким образом, 1|0,2|0 будет сначала вызывать оценку 1|0, но этот результат отбрасывается, а общее значение имеет значение 2|0.

Оператор запятой является общим для многих языков, которые получают их синтаксис выражения из С. (Для всех я знаю, C получил его где-то еще, это вряд ли революционная концепция.) Поскольку такие языки позволяют выражение — только один выражение — должно появиться в нескольких интересных грамматических ситуациях, и поскольку выражения могут (и часто делать) иметь побочные эффекты, иногда бывает удобно пробивать несколько отдельных выражений в то место, где язык действительно хочет только одного. Тем не менее, часто есть более чистые и лучшие способы делать что-то. В JavaScript я лично предпочел бы использовать сразу вызываемую функцию. Это больше печатает и, вероятно, немного хуже по соображениям производительности, но я думаю, что это намного чище, потому что это позволяет изолированное пространство имен для временных переменных и более вовлеченной логики.

+0

Этот ответ является хорошим объяснением для второго случая, но не учитывает первый случай. Может ли это быть добавлено? –

+0

@PlatinumAzure oh sure - Я думал, что первый из них более очевиден, но, вероятно, не для людей, не знакомых с JavaScript и C-подобными языками. – Pointy

4

Чтобы понять это, вам необходимо посмотреть на operator precedence table.

Выражение 1|0,2|0 имеет поразрядный или более высокий приоритет, чем оператор запятой, поэтому он эквивалентен (1|0), (2|0). comma operator оценивает оба операнда и возвращает второй, поэтому вы получаете значение (2|0). Это значение составляет 2.

Выражение 1|0+','+2|0 имеет дополнение с более высоким приоритетом, чем поразрядное, или, таким образом, оно равно 1|(0+','+2)|0.Результат 0+','+2 равен «0,2», который не является числовым, поэтому он вычисляет NaN в числовых операциях. Он принуждает 0 в побитовом-или, так что оставляет 1|0|0, и результат, который равен 1.

+1

'" 0,2 "' не преобразовывается в '0', вместо этого он дает« NaN ». Попробуйте сами: '+ (" 0,2 ")' –

+0

@MattiasBuelens. Он заканчивается как '0' по крайней мере в этой операции – Ian

+0

@Ian Это правда, но его ответ кажется, что он оценивает' 0', потому что он частично разбирает «0,2» '(вплоть до', '), что не так. '|' Заставляет 'NaN' (результат создания' 0,2 "' a 'Number') в' 0'. –

0

From MDN:

Оператор запятой оценивает оба операнда (слева направо) и возвращает значение второго операнда.

Таким образом, в 1|0,2|0, первые два выражения 1|0 и 2|0 вычисляются слева направо, а затем результат последнего выражения (2|0) возвращается. 1|0 === 1 и 2|0 === 2, поэтому результатом последнего выражения является 2, и это возвращается.

В 1|0+','+2|0 запятая отображается в строковой литерале, которая объединена с 0 и 2. Все это оценивается как следует:

  1. (1 | ((0+',')+2)) | 0
  2. (1 | ('0,'+2))) | 0 (+ номер строки = конкатенация)
  3. (1 | '0,2') | 0 (строка + число = конкатенация)
  4. (1 | NaN) | 0 (побитовое ИЛИ нуждается число операндов. 0,2 не может быть преобразован, вместо этого NaN)
  5. 1 | 0 (побитовое ИЛИ имеет дело только с целыми числами, поэтому с плавающей точкой NaN отливают 0)
  6. 1
Смежные вопросы