Begitu banyak jawaban melakukan setengah pekerjaan. Ya, !!X
bisa dibaca sebagai "kebenaran X [diwakili sebagai boolean]". Tetapi !!
secara praktis, tidak penting untuk menentukan apakah suatu variabel tunggal (atau bahkan jika banyak variabel) benar atau salah. !!myVar === true
sama dengan adil myVar
. Membandingkan !!X
dengan boolean "nyata" tidak terlalu berguna.
Apa yang Anda peroleh !!
adalah kemampuan untuk memeriksa kebenaran beberapa variabel terhadap satu sama lain dengan cara yang berulang, standar (dan ramah JSLint).
Cukup casting :(
Itu adalah...
0 === false
adalah false
.
!!0 === false
adalah true
.
Di atas tidak begitu berguna. if (!0)
memberi Anda hasil yang sama dengan if (!!0 === false)
. Saya tidak bisa memikirkan kasus yang baik untuk casting variabel ke boolean dan kemudian membandingkan dengan boolean "benar".
Lihat "== dan! =" Dari arah JSLint (catatan: Crockford memindahkan situsnya sedikit; tautan itu mungkin akan mati pada beberapa titik) untuk sedikit alasan:
Operator == dan! = Melakukan paksaan sebelum membandingkan. Ini buruk karena menyebabkan '\ t \ r \ n' == 0 menjadi benar. Ini bisa menutupi kesalahan tipe. JSLint tidak dapat secara andal menentukan apakah == digunakan dengan benar, jadi yang terbaik adalah tidak menggunakan == dan! = Sama sekali dan selalu menggunakan operator === dan! == yang lebih andal.
Jika Anda hanya peduli bahwa suatu nilai itu benar atau salah, maka gunakan formulir singkat. Dari pada
(foo != 0)
hanya mengatakan
(foo)
dan bukannya
(foo == 0)
mengatakan
(!foo)
Perhatikan bahwa ada beberapa kasus tidak intuitif di mana boolean akan dilemparkan ke nomor ( true
dilemparkan ke 1
dan false
ke 0
) ketika membandingkan boolean dengan nomor. Dalam hal ini, !!
mungkin bermanfaat secara mental. Meskipun, sekali lagi, ini adalah kasus di mana Anda membandingkan boolean non-boolean dengan hard-typed, yang merupakan, imo, kesalahan serius. if (-1)
masih cara untuk pergi ke sini.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
Dan hal-hal menjadi lebih gila tergantung pada mesin Anda. WScript, misalnya, memenangkan hadiah.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Karena beberapa sejarah Windows jive , itu akan menampilkan -1 di kotak pesan! Cobalah di prompt cmd.exe dan lihat! Tapi WScript.echo(-1 == test())
tetap memberi Anda 0, atau WScript false
. Mengalihkan pandangan. Itu mengerikan.
Membandingkan kebenaran :)
Tetapi bagaimana jika saya memiliki dua nilai, saya perlu memeriksa kebenaran yang sama?
Berpura-puralah kita memiliki myVar1 = 0;
dan myVar2 = undefined;
.
myVar1 === myVar2
adalah 0 === undefined
dan jelas salah.
!!myVar1 === !!myVar2
benar !!0 === !!undefined
dan benar! Kebenaran yang sama! (Dalam hal ini, keduanya "memiliki kebenaran palsu".)
Jadi satu-satunya tempat Anda benar-benar perlu menggunakan "variabel boolean-cast" adalah jika Anda memiliki situasi di mana Anda memeriksa apakah kedua variabel memiliki kebenaran yang sama , bukan? Yaitu, gunakan !!
jika Anda perlu melihat apakah dua vars keduanya benar atau keduanya palsu (atau tidak), yaitu, dengan kebenaran yang sama (atau tidak) .
Saya tidak bisa memikirkan kasus penggunaan yang hebat, tidak dibuat-buat untuk itu begitu saja. Mungkin Anda memiliki "tautan" bidang dalam formulir?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Jadi sekarang jika Anda memiliki kebenaran untuk keduanya atau kepalsuan untuk nama dan usia pasangan, Anda dapat melanjutkan. Kalau tidak, Anda hanya punya satu bidang dengan nilai (atau pernikahan yang diatur sangat awal) dan perlu membuat kesalahan tambahan pada errorObjects
koleksi Anda .
EDIT 24 Okt 2017, 6 Feb 19:
Perpustakaan pihak ketiga yang mengharapkan nilai Boolean eksplisit
Inilah kasus yang menarik ... !!
mungkin berguna ketika lib pihak ke-3 mengharapkan nilai Boolean eksplisit.
Misalnya, False in JSX (React) memiliki arti khusus yang tidak dipicu oleh kepalsuan sederhana. Jika Anda mencoba mengembalikan sesuatu seperti yang berikut di BEJ Anda, mengharapkan int di messageCount
...
{messageCount && <div>You have messages!</div>}
... Anda mungkin terkejut melihat React render a 0
saat Anda memiliki nol pesan. Anda harus secara eksplisit mengembalikan false agar JSX tidak di-render. Pernyataan di atas kembali 0
, yang dibuat oleh BEJ dengan senang hati, sebagaimana mestinya. Itu tidak bisa mengatakan Anda tidak punya Count: {messageCount && <div>Get your count to zero!</div>}
(atau sesuatu yang kurang dibuat-buat).
Salah satu perbaikan melibatkan bangbang, yang memaksa 0
ke dalam !!0
, yang false
:
{!!messageCount && <div>You have messages!</div>}
Dokumen BEJ menyarankan Anda untuk lebih eksplisit, menulis kode komentar sendiri, dan menggunakan perbandingan untuk memaksa ke Boolean.
{messageCount > 0 && <div>You have messages!</div>}
Saya lebih nyaman menangani sendiri kepalsuan dengan ternary -
{messageCount ? <div>You have messages!</div> : false}
Kesepakatan yang sama dalam naskah: Jika Anda memiliki fungsi yang mengembalikan boolean (atau Anda memberikan nilai ke variabel boolean), Anda [biasanya] tidak dapat mengembalikan / menetapkan nilai boolean-y; itu haruslah boolean yang sangat diketik. Ini berarti, jika iff myObject
sangat diketik , return !myObject;
berfungsi untuk fungsi mengembalikan boolean, tetapi return myObject;
tidak. Anda harus return !!myObject
mencocokkan ekspektasi Typcript.
Pengecualian untuk naskah? Jika myObject
adalah any
, Anda kembali ke Wild West JavaScript dan dapat mengembalikannya tanpa !!
, bahkan jika jenis pengembalian Anda adalah boolean.
Perlu diingat bahwa ini adalah konvensi JSX & Typcript , bukan yang melekat pada JavaScript .
Tetapi jika Anda melihat aneh 0
di JSX Anda, pikirkan manajemen yang salah.