Почему эти троичные выражения дают разные результаты?

#javascript #reduce

#javascript #уменьшить

Вопрос:

Мое первое сокращение возвращает выражение вида: a (condition)? b : c , а мое второе сокращение возвращает эквивалентное (???) выражение: (condition)? a b : a c Почему они ведут себя по-разному?

 function addressLengthWrong(address) {
  let keys = ['street', 'city', 'state', 'zip']
  return keys.reduce((acc, key) => acc   (address[key]) ? address[key].length : 0, 0)
}

let address = {
  street: 'My Street',
  city: '',
  state: '',
  zip: ''
}
console.log(`wrong address len ${addressLengthWrong(address)}`)

address.zip = '01234'
console.log(`wrong address len ${addressLengthWrong(address)}`)  

Запуск альтернативы…

 function addressLengthCorrect(address) {
  let keys = ['street', 'city', 'state', 'zip']
  return keys.reduce((acc, key) => (address[key]) ? acc   address[key].length : acc, 0)

}

address = {
  street: 'My Street',
  city: '',
  state: '',
  zip: ''
}
console.log(`correct address len ${addressLengthCorrect(address)}`)

address.zip = '01234'
console.log(`correct address len ${addressLengthCorrect(address)}`)  

У меня возбужденное чувство, что я собираюсь узнать что-то новое. Что здесь происходит?

Комментарии:

1. Приоритет оператора : ... ... приоритет: 13, ... ? ... : ... приоритет: 4; выигрывает большее значение

Ответ №1:

Ваш порядок скобок неправильный. Попробуйте это:

 function addressLengthWrong(address) {
  let keys = ['street', 'city', 'state', 'zip']
  return keys.reduce((acc, key) => acc   (address[key] ? address[key].length : 0), 0)
}
  

Вы должны заключить все троичное выражение в круглые скобки, иначе acc будет включено.

Кроме того, чтобы процитировать ответ Андреаса:

... ... precedence: 13, ... ? ... : ... precedence: 4; the higher value 'wins'

Комментарии:

1. Хорошо. Понятно. Спасибо. Другими словами, мое неправильное выражение похоже на (a (condition)) ? b : c итак, Javascript позволяет мне добавлять целое число к bool, а затем интерпретирует сумму как bool, который выбирает целое число? Чокнутый!

2. Почему он должен заключать все это в круглые скобки? Каков порядок приоритета?

3. @Chipster Смотрите мой комментарий

4. андреас хорошо подвел итог

5. @Andreas это имеет смысл. Я думаю, что ответ мог бы быть улучшен, если бы в него была включена эта информация.

Ответ №2:

Я думаю, это потому, что троичная операция некорректна в первой, и она не улавливает начальное значение. Вместо сложения ( ) используйте = в накопителе.

 let a = 1, b = 2
let c = 0

c   a === 1 ? a : b //  fails, c = 0

c  = a === 1 ? a : b //  success, c = 1