Разница в отрицании оператора if

avatar
Daniel
8 августа 2021 в 20:50
55
2
0

Я пишу некоторые коды для себя, чтобы лучше изучить JS, и мне было интересно, есть ли какая-либо разница в условии отрицания в операторе if с оператором, который сравнивает два значения, или с оператором, который отрицает все условие.

Первый выглядит так:

if(value != 'foo') {}

И второй:

if(!value == 'foo') {}

Есть ли какие-то из них лучше, более подходящие?

Спасибо!

Источник
derpirscher
8 августа 2021 в 20:54
1

Они семантически различны. Второй всегда будет false, потому что !value всегда является логическим значением, поэтому не будет равно foo. Вы наверное хотели написать if (!(value == 'foo')

ulou
8 августа 2021 в 21:03
2

if(value != 'foo') {} совпадает с if(!(value == 'foo')) {}. Первый просто читабельнее и предпочтительнее в 99% случаев. Ваш второй пример не имеет смысла, потому что в большинстве случаев значение будет истинным.

Ответы (2)

avatar
shadow-blake
8 августа 2021 в 21:00
1

Основное объяснение этой разницы состоит в том, что когда вы выполняете value != 'foo', вы проверяете, не равно ли value 'foo', но когда вы делаете !value == 'foo', вы оцениваете значение как ' true" или "false", затем проверяется, равна ли эта логическая оценка "foo".

Например

let value = 'foo'

value == 'foo' //evaluates to true
value != 'foo' //evaluates to false
!value //evaluates to false
!value == 'foo' //also evaluates to false

Вот еще один пост, в котором рассказывается об этих операторах https://coderhelper.com/a/8616501/16600680

avatar
Samathingamajig
8 августа 2021 в 20:57
1

Первый,

if(value != 'foo') {}

не только более удобочитаемый, но и единственный, который работает так, как вы ожидаете.

Это означает, что "значение не равно 'foo'".

Ваш второй,

if(!value == 'foo') {}

означает "равна ли инвертированная истинность значения 'foo'"

(он преобразует value в логическое значение и берет его отрицательную версию)

Если, однако, вы хотели сказать

if (!(value == 'foo'))

для второго, то ответ все тот же, что лучше: первый.

Нет причин расширять оператор, делая его еще более запутанным, когда != уже существует.


Посмотрите на эту демонстрацию:

const value1 = "foo";
const value2 = "bar";

console.log("expected", false, true);
console.log("first option", value1 != 'foo', value2 != 'foo');
console.log("second option", !value1 == 'foo', !value2 == 'foo');
console.log("modifed second option", !(value1 == 'foo'), !(value2 == 'foo'));
тест "фу" "бар"
ожидаемый ложь истина
первый вариант ложь истина
второй вариант ложь ложь
модифицированный второй вариант ложь истина

Как видите, указанный вами второй вариант всегда будет приводить к false, потому что он проверяет, равен ли true (если значение является пустой строкой) или false (если значение является непустой строкой) строковый литерал foo