булева в операторі if


144

Сьогодні я отримав зауваження щодо коду, враховуючи те, як я перевіряю, чи є змінна правдою чи неправдою в шкільному завданні.

Код, який я написав, був приблизно таким:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

Вони сказали, що краще / акуратніше написати це так:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

Зауваження, яке я отримав щодо частини "=== true", було те, що вона не потрібна і може створювати плутанину.

Однак моя ідея полягає в тому, що краще перевірити, чи є змінна булева чи ні, тим більше, що Javascript є розробленою мовою.

У другому прикладі рядок також повертає "щось";

Тож моє запитання; Чи акуратніше втратити частину "=== true" у майбутньому, чи добре перевірити також тип змінної.

Редагувати: У моєму "справжньому" коді булевий символ відображає, було чи видалено зображення чи ні, тому єдині значення, які коли-небудь повинні мати boolValue, - це істинні чи неправдиві.

Наприклад, 0 і 1 не повинні бути в цій змінній.


4
можна читати і використовувати хорошу практику ===
Piyas De

2
+1 для === true. Уникайте плутанини !!
гашу

1
@gashu Розглянемо [0] === trueоцінку як хибну.
RestingRobot

1
@Jlange чи не так? Будь ласка, поясніть
gashu

Що я мав на увазі під цим, це те, що якщо ви просто хотіли б перевірити наявність "truthy" існування, це твердження буде невдалим, хоча воно повинне оцінювати як істинне ([0] оцінює в true, але не без перетворення типу). Це дійсно залежить від того, що ви намагаєтеся зробити зі своєю заявою. Використовуйте, === trueколи вам потрібно переконатися, що умова точно дорівнює true.
RestingRobot

Відповіді:


222

По-перше, факти:

if (booleanValue)

Буде задовольняти ifоператор за будь-яке значення truthy, booleanValueвключаючи true, будь-яке ненульове число, будь-яке не порожнє значення рядка, будь-яке посилання на об'єкт або масив тощо ...

З іншої сторони:

if (booleanValue === true)

Це задовольнить ifумову лише у тому випадку, коли booleanValueвоно точно дорівнює true. Жодна інша ціннісна цінність її не задовольнить.

З іншого боку, якщо ви це зробите:

if (someVar == true)

Тоді, що Javascript буде робити, це ввести примусовий trueвідповідність типу, someVarа потім порівняти дві змінні. Існує безліч ситуацій, коли це, мабуть, не те, що б хтось мав намір. Через це в більшості випадків ви хочете уникати, ==оскільки існує досить довгий набір правил щодо того, як Javascript буде вводити примушування двох речей одного типу, і якщо ви не розумієте всі ці правила і не зможете передбачити все, що може зробити інтерпретатор JS, коли враховуючи два різні типи (чого більшість розробників JS не може), ймовірно, ви хочете ==повністю уникати .

Як приклад того, як це можна заплутати:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

Щодо значення 2, ви б подумали, що 2це трихосе значення, тому воно вигідно порівнятиметься true, але це не так, як працює примус типу. Це перетворення значення правої руки у відповідність типу значення лівої руки та перетворення trueїї на число, 1тобто порівняння2 == 1 яке, звичайно, не те, що ви, ймовірно, планували.

Отже, остерігайтеся покупця. Це, мабуть, найкраще уникати ==майже у всіх випадках, якщо ви чітко не знаєте типів, які ви будете порівнювати, і не знаєте, як працюють усі можливі алгоритми примусу типів.


Отже, це дійсно залежить від очікуваних значень booleanValueта того, як ви хочете, щоб код працював. Якщо ви заздалегідь знаєте, що матиме trueабо має falseзначення лише колись , тоді явно порівнюйте його

if (booleanValue === true)

просто зайвий код і непотрібний і

if (booleanValue)

є більш компактним і, можливо, чистішим / кращим.

Якщо, з іншого боку, ви не знаєте, що booleanValueможе бути, і ви хочете перевірити, чи справді це встановлено, якщо trueінші автоматичні перетворення типу не дозволені, тоді

if (booleanValue === true)

це не тільки гарна ідея, але і необхідна.


Наприклад, якщо ви подивитеся на реалізацію .on()в jQuery, вона має необов'язкове повернене значення. Якщо зворотний зв'язок повернеться false, jQuery автоматично зупинить поширення події. В даному конкретному випадку, так як JQuery хоче поширення зупинити тільки , якщо falseбув повернутий, вони перевіряють повертається значення для явної формі, === falseтому що вони не хочуть undefinedабо 0або ""або що - небудь ще , що буде автоматично набирати конвертування в НЕВІРНО задовольняти порівняння.

Наприклад, ось код зворотного виклику події jQuery:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

Ви можете бачити, що jQuery явно шукає ret === false.

Але в коді jQuery також є багато інших місць, де простіша перевірка є доцільною, враховуючи бажання коду. Наприклад:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...

Я думав над цим питанням деякий час, але не мав можливості знайти когось, щоб його задати. Буду вдячний, якщо ви могли поглянути. stackoverflow.com/questions/32615466/…
ммм

Ця відповідь не зовсім коректна. 'x == true' не буде істинним для ненульових чисел.
Темох

@Teemoh - я не розумію ваш коментар. Дивіться jsfiddle.net/jfriend00/89h8d8tm .
jfriend00

1
Я просто хочу сказати, що "if (x)" - це не те саме, що "if (x == true)", як ви писали в першому абзаці своєї відповіді. 'if (x)' явно перетворить 'x' в бульне подання. 'if (x == true)' буде використовувати алгоритм абстрактного порівняння EcmaScript. Ви писали, що "if (x == true)" буде істинним для будь-якого нульового числа, непустого рядка або будь-якого об'єкта. Це просто неправильно. Якщо я запускаю ваш приклад з 2 замість 1, він не працюватиме.
Teemoh

2
@Teemoh - я бачу вашу думку. Відповідь виправлено та уточнили, і я додав розділ про примус типу, який показує, як він може робити несподівані речі.
jfriend00

40

Якщо ви пишете:, if(x === true)це буде правдою лише для x = true

Якщо ви пишете:, if(x)це буде правдою для будь-якого x, який не є: '' (порожній рядок), false, null, undefined, 0, NaN.


(порожня рядок), false, null, undefined, 0, NaN
Oliboy50

Не забувайте NaNі -0.
хайкам

8

У звичайній "if" змінна буде примушена до булевої, і вона використовує toBoolean на об'єкті: -

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

Але порівняння з === не має примусу будь-якого типу, тому вони повинні бути рівними без примусу.

Якщо ви говорите, що об'єкт може бути навіть булевим, то, можливо, вам доведеться розглянути більше, ніж просто істинне / хибне.

if(x===true){
...
} else if(x===false){
....
} else {
....
}

5

Це залежить від вашої справи. Можливо, має сенс і перевірити тип, але якщо це лише прапор, це не так.


===Порівняння не виконує тип примусу. Таким чином, код OP ефективно перевіряє тип прапора. Він досягає успіху лише в тому випадку, якщо значення булеве і істинне.
Джессі Халлетт

Дозвольте перефразувати. Якщо ви знаєте, що це буде правдою чи помилкою, це не має значення.
Вен

5

Загалом, пропускати чистіше і простіше === true.

Однак у Javascript ці твердження різні.

if (booleanValue)буде виконуватися , якщо booleanValueце truthy - нічого, крім 0, false, '', NaN, null, і undefined.

if (booleanValue === true)буде виконуватися лише в тому випадку, якщо booleanValueточно дорівнює true.


У чому саме я хочу бути впевненим, навіть коли я хочу лише, щоб boolValue була правдивою чи помилковою. Змінна встановлюється в коді кілька разів істинно / хибно. Я знаю, що коли я пишу код, але якщо я ще раз перевіряю код через рік, то його просто великий знак питання, якщо я не перечитав все правильно?
DirkZz

@aldanux: На жаль; Я мав на увазі ''.
СЛАкс

4

Оператор ідентичності (===)поводиться однаково з (==)оператором рівності, за винятком того, що не проводиться перетворення типів, і типи повинні бути однаковими, щоб вважати рівними.


Ваше останнє речення неправильне. Спробуйте два свої твердження if (booleanValue)і if (booleanValue==true)коли booleanValueце 2. Ці два твердження не дають однакового результату.
jfriend00

Цікаво. Я візьму за це ваше слово. Я думав у світі ObjC / C / C ++, в JS я припускаю, що ви правильні, оскільки типи даних у JS можна змінити, а 2 == true не оцінить кількість, якщо тоді.
ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ Apollo

1
Дивіться мою відповідь вище для цього конкретного прикладу. Це пов'язано з тим, як Javascript здійснює автоматичне перетворення типів, щоб порівняти два значення різних типів.
jfriend00

3

Оскільки перевірене значення Booleanбажано використовувати його безпосередньо для меншого кодування, і воно взагалі зробило те саме==true


2

Оскільки ви вже ініціалізувались чітко як bool, я думаю, що ===оператор не потрібен.


2

Якщо змінна може коли-небудь набувати булевих значень, тоді розумно використовувати коротший синтаксис.

Якщо це потенційно може бути призначено інші типи, і вам потрібно відрізнити trueвід 1або "foo", тоді ви повинні використовувати === true.


2

Я думаю, що ваші міркування є здоровими. Але на практиці я виявив, що набагато частіше опускати ===порівняння. Я думаю, що для цього є три причини:

  1. Зазвичай це не додає значення виразу - це у тих випадках, коли значення, як відомо, все-таки булеве.
  2. Оскільки в JavaScript існує велика невизначеність типів, змушення перевірки типу, як правило, кусає вас, коли ви отримуєте несподіваний undefinedабоnull значення. Часто ви просто хочете, щоб ваш тест провалився в таких випадках. (Хоча я намагаюся врівноважити цю точку зору девізом "невдало швидко").
  3. Програмісти JavaScript люблять грати швидко і безперервно з типами - особливо в булевих виразах - тому що ми можемо.

Розглянемо цей приклад:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

Я думаю, що подібний код не рідкість. Він обробляє випадки , коли getInput()повертається undefined, nullабо порожній рядок. Через дві булеві оцінки submitInput()викликається лише якщо даний вхід є рядком, який містить символи, що не містять пробілів.

У JavaScript &&повертає свій перший аргумент, якщо він хибний або другий аргумент, якщо перший аргумент є правдивим; так normalizedбуде, undefinedякщо не someStringбуло визначено тощо. Це означає, що жоден із входів до булевих виразів, наведених вище, насправді не є булевими значеннями.

Я знаю, що багато програмістів, які звикли до сильної перевірки типу, переглядаючи подібний код. Але зауважте, що застосування сильного введення тексту, швидше за все, вимагатиме явних перевірок nullчи undefinedзначень, які б захаращували код. У JavaScript це не потрібно.


1

Це залежить. Якщо ви стурбовані тим, що ваша змінна може закінчитися як щось, що вирішує значення TRUE. Тоді ретельна перевірка є обов'язковою. Інакше це залежить від вас. Однак я сумніваюся, що синтаксис whatever == TRUEколи-небудь заплутає всіх, хто знав, що вони роблять.


1

У Javascript ідея boolean досить неоднозначна. Врахуйте це:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

Отже, коли ви використовуєте оператор if (або будь-який інший оператор управління), не потрібно використовувати "boolean" тип var. Тому, на мою думку, "=== правдива" частина вашого висловлювання непотрібна, якщо ви знаєте, що це булева, але абсолютно необхідна, якщо ваша цінність є неоднозначною "трихою" вар. Більше про булеви в javscript можна прочитати тут .



1

Також можна протестувати з булевим об'єктом, якщо вам потрібно протестувати об'єкт error={Boolean(errors.email)}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.