Существуют ли какие-либо выражения машинописного текста `a`, при которых истинность` a` отличается от `!! a`?

В Javascript почти все выражения (все выражения?) Имеют значение «истинности». Если вы поместите выражение в оператор, который ожидает логическое значение, оно будет оцениваться как логический эквивалент. Например:

let a = 'foo'

if (a) {
  console.log('a is truthy!');
}
// Will print 'a is truthy!'.

На некоторых рабочих местах принято преобразовывать выражение в фактическое логическое значение, дважды отрицая его:

let a = 'foo'

if (!!a) {
  console.log('a is truthy!');
}
// Will print 'a is truthy!'.

Мой вопрос: это просто вопрос стиля? Это просто для того, чтобы сообщить кому-то, кто читает код, что мы действительно осознаем, что a не является логическим, но мы все равно намерены оценивать его как таковое? Или существуют какие-либо выражения или значения a, где if (a) фактически оценивает логическое значение, отличное от if (!!a)?

6
0
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Правдивость a и !!a всегда будет одинаковой.

ToBoolean - это просто статический поиск и не выполняет какой-либо пользовательский код на любом этапе. Использование ! применяет ToBoolean и отменяет результат. if также применяет ToBoolean и принимает результат. Оба на самом деле мало что делают. Поскольку двойное отрицание является идентичностью, и ToBoolean ничего не меняет, если вход уже является логическим, они всегда будут одинаковыми.

TL; DR; в псевдокоде «ToBoolean (a) === ToBoolean (booleanNot (ToBoolean (booleanNot (ToBoolean (a)))))».


Обратите внимание, что можно изменять переменную при каждом поиске и производить тесты, которые могут сбивать с толку, но на самом деле не опровергают вышеизложенное. a просто заменяется после первой оценки - использовался ли !! или нет, не имеет значения:

let x = 0;
let objectEnvironment = { get a() { return x++; } };
with(objectEnvironment){
  if (a) console.log("truthy?");
  if (!!a) console.log("double negated truthy?");
}

Если вы поменяете местами использование a и !!a в приведенном выше примере, результат не изменится. Обратите внимание, что with уже является ошибкой в ​​строгом режиме и не должен использоваться. Это только показало, что GetValue можно использовать для выполнения пользовательского кода. Однако его невозможно обнаружить независимо от того, использовалось ли логическое «не» или нет, поэтому создание условия для него не должно работать.

Is this merely a matter of style? Is it purely to communicate to someone reading the code that we really recognize that a is not a boolean, but that we intend to evaluate it as such anyway?

См. Зачем использовать if (!! err)?

Or do there exist any expressions or values of a where if (a) actually evaluates to a different boolean value than if (!!a)?

Нет, если a всегда ссылается на одно и то же (например, это не геттер, который возвращает случайный контент). См. Спецификацию:

Оператор логического НЕ (!)

  1. Let expr be the result of evaluating UnaryExpression.
  2. Let oldValue be ToBoolean(? GetValue(expr)).
  3. If oldValue is true, return false.
  4. Return true.

Заявление if

  1. Let exprRef be the result of evaluating Expression.
  2. Let exprValue be ToBoolean(? GetValue(exprRef)).
  3. If exprValue is true, then
    • Let stmtCompletion be the result of evaluating the first Statement.
  4. Else,
    • Let stmtCompletion be the result of evaluating the second Statement.
  5. Return Completion(UpdateEmpty(stmtCompletion, undefined)).

И оператор логического НЕ, и оператор if вызывают функцию ToBoolean. В результате невозможно, чтобы if (a) и if (!!a) были разными (все еще предполагая, что оба a относятся к одному и тому же).

Другие вопросы по теме