15 Desember 2021

Operator logika

Ada tiga operator logika di JavaScript: || (OR), && (AND), ! (NOT).

Meski mereka dipanggil ???logika???, mereka bisa diaplikasikan ke nilai tipe apapun, bukan cuma boolean. Hasil mereka bisa juga tipe apapun.

Mari kita lihat detilnya.

|| (OR)

Operator ???OR??? diwakili dengan dua simbol garis vertical:

result = a || b;

Di pemrograman klasik, logika OR gunanya cuma untuk memanipulasi nilai boolean. Jika argumennya ada yang true, ia mengembalikan true, tapi jika tidak, maka ia mengembalikan false.

Di JavaScript, operator ini agak tricky dan lebih kuat. Tapi pertama-tama, ayo kita lihat apa yang terjadi pada nilai boolean.

Ada empat kemungkinan kombinasi logika:

alert( true || true );   // true
alert( false || true );  // true
alert( true || false );  // true
alert( false || false ); // false

Seperti yang kita lihat, hasilnya selalu true kecuali jika kedua operand sama-sama false.

Jika operand bukan boolean, ia dikonversi ke boolean untuk evaluasi.

Misalnya, angka 1 diperlakukan sebagai true, angka 0 sebagai false:

if (1 || 0) { // bekerja seperti if( true || false )
  alert( 'truthy!' );
}

Seringkali, OR || digunakan di pernyataan if untuk menguji apakah ada satu kondisi manapun yang true.

Misalnya:

let hour = 9;

if (hour < 10 || hour > 18) {
  alert( 'The office is closed.' );
}

Kita bisa menyampaikan kondisi lebih:

let hour = 12;
let isWeekend = true;

if (hour < 10 || hour > 18 || isWeekend) {
  alert( 'The office is closed.' ); // akhir minggu
}

OR "||" mencari nilai benar pertama

Logika di atas memang klasik. Sekarang, mari bawa fitur ???extra??? JavaScript.

Algoritma luas bekerja seperti berikut.

Untuk nilai yang diORkan:

result = value1 || value2 || value3;

Operator OR || melakukan hal berikut:

  • Mengevaluasi operand dari kiri ke kanan.
  • Untuk tiap operand, konversikan ia ke boolean. Jika hasilnya true, stop dan mengembalikan nilai original dari operand.
  • Jika semua operand telah dievaluasi (misal semuanya false), mengembalikan operand terakhir.

Nilai dikembalikan di bentuk originalnya, tanpa konversi.

Dengan kata lain, rantai OR "||" mengembalikan nilai truthy pertama atau yang terakhir jika tak ada nilai benar.

Misalnya:

alert( 1 || 0 ); // 1 (1 truthy)
alert( true || 'no matter what' ); // (true ialah truthy)

alert( null || 1 ); // 1 (1 ialah nilai truthy pertama)
alert( null || 0 || 1 ); // 1 (nilai truthy pertama)
alert( undefined || null || 0 ); // 0 (semua falsy, mengembalikan nilai terakhir)

Hal ini menjadikan penggunaan yang menarik dibanding ???OR booleanpure, classical, boolean-only OR???.

  1. Dapatkan nilai truthy dari daftar variabel atau expresi.

    Untuk contoh, kita punya variabel firstName, lastName dan nickName, semuanya bersifat opsional.

    Kita gunakan OR || untuk memilih satu-satunya yang memiliki data dan menampilkannya (atau anonymous jika belum ada yang ditentukan atau di set):

    let firstName = "";
    let lastName = "";
    let nickName = "SuperCoder";
    
    alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder

    Jika semua variabel bernilai falsy, Anonymous akan muncul.

  2. Evaluasi Short-circuit.

    Fitur lainnya dari operator OR || adalah evaluasi ???short-circuit???.

    Itu berarti bahwa || memproses argumennya sampai nilai pertama bersifat truthy tercapai, lalu nilainya dikembalikan langsung, bahkan tanpa menyentuh argumen lainnya.

    Pentingnya dari fitur ini menjadi jelas jika sebuah operan bukan hanya sebuah nilai, tapi sebuah ekspresi yang melakukan aksi, seperti assignment sebuah variabel atau sebuah pemanggilan fungsi.

    Didalam contoh dibawah, hanya pesan kedua yang di jalankan:

    true || alert("not printed");
    false || alert("printed");

    Di baris pertama, operator OR || langsung berhenti mengevaluasi karena nilai pertama bersifat true, jadi alertnya tidak berjalan.

    Terkadang, orang-orang menggunakan fitur ini untuk mengeksekusi perintah hanya jika kondisi di paling kiri bersifat falsy.

&& (AND)

Operator AND diwakili dua ampersand &&:

result = a && b;

Dalam pemrograman klasik, AND mengembalikan true jika kedua operand sama-sama truthy dan false jika sebaliknya:

alert( true && true );   // true
alert( false && true );  // false
alert( true && false );  // false
alert( false && false ); // false

Contoh dengan if:

let hour = 12;
let minute = 30;

if (hour == 12 && minute == 30) {
  alert( 'The time is 12:30' );
}

Sama seperti OR, nilai apapun boleh menjadi operand dari AND:

if (1 && 0) { // dievaluasi sebagai true && false
  alert( "won't work, because the result is falsy" );
}

AND ???&&??? mencari nilai falsy pertama

Misal ada beberapa nilai di-AND-kan:

result = value1 && value2 && value3;

Yang dilakukan operator AND && adalah sebagai berikut:

  • Mengevaluasi operand dari kiri ke kanan.
  • Untuk tiap operand, konversi ia ke boolean. Jika hasilnya false, stop dan kembalikan nilai original operand tersebut.
  • Jika semua operand dievaluasi (i.e. semua truthy), mengembalikan operand terakhir.

Dengan kata lain, AND mengembalikan nilai falsy pertama atau nilai terakhir jika tak ketemu satupun nilai falsy.

Aturan di atas mirip dengan OR. Bedanya ialah AND mengembalikan niai falsy pertama sedangkan OR mengembalikan nilai truthy pertama.

Misalnya:

// jika operand pertama truthy,
// AND mengembalikan operand kedua:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5

// jika operand pertama falsy,
// AND mengembalikan itu. Operand kedua diabaikan
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0

Kita juga bisa mengoper beberapa nilai dalam satu barus. Lihat bagaimana nilai falsy pertama dikembalikan:

alert( 1 && 2 && null && 3 ); // null

Ketika semua nilai truthy, nilai terakhir dikembalikan:

alert( 1 && 2 && 3 ); // 3, the last one
Precedence of AND && is higher than OR ||

Presedensi operator AND && lebih tinggi dari OR ||.

Jadi kode a && b || c && d esensinya sama dengan jika expresi && dibungkus tanda kurung: (a && b) || (c && d).

Jangan ganti if dengan || atau &&

Terkadang, orang-orang menggunakan operator AND && untuk "memperpendek instruksi if".

Misalnya:

let x = 1;

(x > 0) && alert( 'Greater than zero!' );

Aksi di bagian kanan && akan diexekusi hanya jika evaluasinya mencapai itu. Yaitu, hanya jika (x > 0) true.

Jadi pada dasarnya kita punya analogi untuk:

let x = 1;

if (x > 0) alert( 'Greater than zero!' );

Walaupun, versi dengan && muncul lebih pendek, if menjadi jelas dan sedikit lebih mudah dibaca. Jadi kita merekomendasikan menggunakannya untuk setiap kebutuhan: gunakan if jika kita ingin if dan gunakan && jika kita ingin AND.

! (NOT)

Operator boolean NOT diwakili dengan tanda exklamasi !.

Syntaxnya cukup simpel:

result = !value;

Operator ini menerima argumen tunggal dan menjalankan hal berikut:

  1. Mengkonversi operand ke tipe boolean: true/false.
  2. Mengembalikan nilai kebalikan.

Misalnya:

alert( !true ); // false
alert( !0 ); // true

NOT ganda !! kadang dipakai untuk mengkonversi nilai ke tipe boolean:

alert( !!"non-empty string" ); // true
alert( !!null ); // false

Yaitu, NOT pertama mengkonversi nilai ke boolean dan mengembalikan kebalikannya, dan NOT kedua membaliknya lagi. Ujungnya, kita punya konversi nilai-ke-boolean biasa.

Ada sedikit cara rewel untuk melakukan hal serupa ??? fungsi Boolean built-in:

alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false

Presedensi NOT ! paling tinggi dari semua operator logika, jadi ia selalu jalan pertama, sebelum && or ||.

Tugas

Apakah keluaran dari kode dibawah?

alert( null || 2 || undefined );

Jawabannya 2, itu nilai truthy pertama.

alert( null || 2 || undefined );

Apa output kode di bawah?

alert( alert(1) || 2 || alert(3) );

Jawabannya: pertama 1, lalu 2.

alert( alert(1) || 2 || alert(3) );

Panggilan alert tak mengembalikan nilai. Atau, dengan kata lain, ia mengembalikan undefined.

  1. Pertama OR || mengevaluasi operand kiri alert(1). Ia menampilkan pesan pertama dengan 1.
  2. alert mengembalikan undefined, jadi OR jalan ke operand kedua mencari nilai truthy.
  3. Operand kedua 2 truthy, jadi eksekusinya disela, 2 dikembalikan dan ditampilkan oleh alert terluar.

Tak akan ada 3, karena evaluasinya tidak mencapai alert(3).

Kode ini akan menampilkan apa?

alert( 1 && null && 2 );

Jawabannya: null, karena null adalah nilai falsy pertama yang ada di daftar.

alert( 1 && null && 2 );

Kode ini akan menampilkan apa?

alert( alert(1) && alert(2) );

Jawabannya: 1, dan kemudian undefined.

alert( alert(1) && alert(2) );

Panggilan alert mengembalikan undefined (ia cuma menampilkan pesan, jadi tak ada kembalian berarti).

Karena itu, && mengevaluasi operand kiri (output 1), dan langsung berhenti, karena undefined adalah nilai falsy. Dan && mencari nilai falsy dan mengembalikannya, jadi begitulah.

Hasilnya akan jadi apa?

alert( null || 2 && 3 || 4 );

Jawabannya: 3.

alert( null || 2 && 3 || 4 );

Presedensi AND && lebih tinggi dari ||, jadi ia jalan pertama.

Hasil dari 2 && 3 = 3, jadi expresinya menjadi:

null || 3 || 4

Sekarang hasilnya jadi nilai truthy pertama: 3.

Tulis satu kondisi ???if??? untuk mengecek bahwa age ada di antara 14 dan 90 secara inklusif.

???Secara inklusif??? artinya bahwa age bisa mencapai 14 atau 90.

if (age >= 14 && age <= 90)

Tulis satu kondisi if untuk mengecek bahwa age BUKAN di antara 14 dan 90 secara inklusif.

Buat dua varian: pertama menggunakan NOT !, kedua ??? tanpaanya.

Varian pertama:

if (!(age >= 14 && age <= 90))

Varian kedua:

if (age < 14 || age > 90)

Mana dari alert berikut yang akan diexekusi?

Hasil expresinya akan jadi seperti apa di dalam if(...)?

if (-1 || 0) alert( 'first' );
if (-1 && 0) alert( 'second' );
if (null || -1 && 1) alert( 'third' );

Jawabannya: pertama dan ketiga akan diexekusi.

Detil:

// Berjalan.
// Hasil dari -1 || 0 = -1, truthy
if (-1 || 0) alert( 'first' );

// Tidak berjalan
// -1 && 0 = 0, falsy
if (-1 && 0) alert( 'second' );

// Eksekusi
// Operator && mempunyai hak yang lebih tinggi daripada ||
// jadi -1 && 1 dieksekusi pertama, dan memberikan rentetan:
// null || -1 && 1  ->  null || 1  ->  1
if (null || -1 && 1) alert( 'third' );

Tulis kode yang meminta login dengan prompt.

Jika pengunjung menekan "Admin", maka prompt untuk katasandi, jika inputannya beruba baris kosong atau Esc ??? tampilkan ???Canceled.???, jika string lain ??? maka tampilkan ???I don???t know you???.

Katasandinya dicek sebagai berikut:

  • Jika ia sama dengan ???TheMaster???, maka tampilkan ???Welcome!???,
  • String lain ??? tampilkan ???Wrong password???,
  • Untuk string kosong atau batal input, tampilkan ???Canceled.???

Skemanya:

Silakan gunakan blok if bersarang. Abaikan kemudahan-baca seluruh kode.

Petunjuk: mengoper inputan kosong ke prompt mengembalikan string kosong ''. Menekan ESC saat prompt mengembalikan null.

jalankan demonya

let userName = prompt("Who's there?", '');

if (userName === 'Admin') {

  let pass = prompt('Password?', '');

  if (pass === 'TheMaster') {
    alert( 'Welcome!' );
  } else if (pass === '' || pass === null) {
    alert( 'Canceled' );
  } else {
    alert( 'Wrong password' );
  }

} else if (userName === '' || userName === null) {
  alert( 'Canceled' );
} else {
  alert( "I don't know you" );
}

Perhatikan indent vertkal di dalam blok if. Mereka secara teknis tak dibutuhkan, tapi membuat kode lebih mudah dibaca.

Peta tutorial