Що таке оператор з двома трубами ( ||)?
Оператор з двома трубами ( ||) є логічним ORоператором . У більшості мов це працює наступним чином:
- Якщо перше значення є
false, воно перевіряє друге значення. Якщо є true, він повертається, trueі якщо є false, він повертаєтьсяfalse .
- Якщо перше значення є
true, воно завжди повертається true, незалежно від другого значення.
Так що в основному це працює так:
function or(x, y) {
if (x) {
return true;
} else if (y) {
return true;
} else {
return false;
}
}
Якщо ви все ще не розумієте, подивіться на цю таблицю:
| true false
------+---------------
true | true true
false | true false
Іншими словами, це помилково лише тоді, коли обидва значення хибні.
Чим він відрізняється в JavaScript?
JavaScript дещо інший, тому що це мова з дуже слабким типом . У цьому випадку це означає, що ви можете використовувати ||оператор зі значеннями, які не є булевими. Хоча це не має сенсу, ви можете використовувати цей оператор, наприклад, з функцією та об'єктом:
(function(){}) || {}
Що там відбувається?
Якщо значення не булеві, JavaScript робить неявне перетворення в булеве . Це означає , що якщо значення falsey (наприклад 0, "", null, undefined(дивись також всі значення falsey в JavaScript )), це буде розглядатися як false; інакше це трактується як true.
Отже, вищенаведений приклад повинен наводити true, оскільки порожня функція є правдою. Ну, це не так. Він повертає порожню функцію. Це тому, що ||оператор JavaScript не працює, як я писав на початку. Це працює наступним чином:
- Якщо перше значення - фальси , воно повертає друге значення .
- Якщо перше значення є truthy , воно повертає перше значення .
Здивувались? Насправді це "сумісно" з традиційним ||оператором. Він може бути записаний у такий спосіб:
function or(x, y) {
if (x) {
return x;
} else {
return y;
}
}
Якщо ви передаєте значення truthy як x, воно повертає x, тобто значення truthy. Тож якщо ви використовуєте його пізніше в ifпункті:
(function(x, y) {
var eitherXorY = x || y;
if (eitherXorY) {
console.log("Either x or y is truthy.");
} else {
console.log("Neither x nor y is truthy");
}
}(true/*, undefined*/));
ви отримуєте "Either x or y is truthy.".
Якби xбув фальси, eitherXorYбув би y. У цьому випадку ви отримаєте, "Either x or y is truthy."якби yбуло неправдою; інакше ти отримаєш "Neither x nor y is truthy".
Актуальне питання
Тепер, коли ви знаєте, як ||працює оператор, ви, напевно, можете самі зрозуміти, що це x = x || yозначає. Якщо xправда, xпризначається x, тому насправді нічого не відбувається; в іншому випадку yпризначено x. Він зазвичай використовується для визначення параметрів за замовчуванням у функціях. Однак це часто вважається поганою практикою програмування , оскільки це заважає передати значення параметра фальси (що не обов'язково undefinedабо null) як параметр. Розглянемо наступний приклад:
function badFunction(/* boolean */flagA) {
flagA = flagA || true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Це виглядає дійсно з першого погляду. Однак, що буде, якби ви перейшли falseяк flagAпараметр (оскільки він бульний, тобто може бути trueабо false)? Це стане true. У цьому прикладі немає ніякого способу встановити flagAв false.
Краще було б чітко перевірити, чи flagAє undefinedтак:
function goodFunction(/* boolean */flagA) {
flagA = typeof flagA !== "undefined" ? flagA : true;
console.log("flagA is set to " + (flagA ? "true" : "false"));
}
Хоча це довше, але це завжди працює, і це легше зрозуміти.
Ви також можете використовувати синтаксис ES6 для параметрів функції за замовчуванням , але зауважте, що він не працює в старих браузерах (наприклад, IE). Якщо ви хочете підтримати ці браузери, вам слід передати свій код на Babel .
Дивіться також Логічні оператори на MDN .
falsy, а не СПОСОБundefined. Кількість разів, яку я бачилаdoWeDoIt = doWeDoIt || true, достатня, щоб змусити мене плакати. (тобтоdoWeDoItтепер ніколи не будеfalse)