Apakah menggunakan == dalam JavaScript pernah masuk akal?

276

Dalam JavaScript, Bagian Yang Baik , Douglas Crockford menulis:

JavaScript memiliki dua set operator kesetaraan: ===dan !==, dan si kembar jahat ==dan !=. Yang bagus bekerja seperti yang Anda harapkan. Jika kedua operan memiliki tipe yang sama dan memiliki nilai yang sama, maka ===hasilkan truedan !==hasilkan false. Si kembar jahat melakukan hal yang benar ketika operan dari jenis yang sama, tetapi jika mereka dari jenis yang berbeda, mereka berusaha untuk memaksa nilai-nilai itu. Aturan-aturan yang dengannya mereka melakukan hal itu rumit dan tidak mudah diingat. Ini adalah beberapa kasus menarik:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Kurangnya transitivitas mengkhawatirkan. Saran saya adalah jangan pernah menggunakan si kembar jahat. Sebaliknya, selalu gunakan ===dan !==. Semua perbandingan hanya menunjukkan produk falsedengan ===operator.

Dengan pengamatan yang tegas ini, apakah pernah ada waktu ketika menggunakan ==sebenarnya cocok?

Robert Harvey
sumber
11
Ini masuk akal di banyak tempat. Setiap kali jelas Anda membandingkan dua hal dari jenis yang sama (ini banyak terjadi dalam pengalaman saya), == vs === hanya turun ke preferensi. Lain kali Anda benar - benar ingin perbandingan abstrak (seperti kasus yang Anda sebutkan dalam jawaban Anda). Apakah itu sesuai tergantung pada konvensi untuk setiap proyek tertentu.
Hei,
4
Mengenai "banyak tempat," menurut pengalaman saya, kasus-kasus di mana tidak masalah melebihi jumlah di mana itu terjadi. Pengalaman Anda mungkin berbeda; mungkin kita memiliki pengalaman dengan berbagai jenis proyek. Ketika saya melihat proyek yang digunakan ==secara default, ===berdiri dan beri tahu saya sesuatu yang penting sedang terjadi.
Hei,
4
Saya tidak berpikir JavaScript berjalan cukup jauh dengan paksaan tipe itu. Seharusnya memiliki lebih banyak opsi opsi pemaksaan, seperti bahasa BS .
Mark Booth
5
Satu tempat yang saya gunakan == adalah ketika membandingkan dropdown id (yang selalu char) dengan model id (yang umumnya int).
Scottie
12
Pengembangan Web @DevSolar masuk akal ketika Anda tidak ingin harus berurusan dengan memproduksi aplikasi asli untuk masing-masing dari 15 platform serta sertifikasi pada App Store monopoli dari setiap platform yang memiliki satu.
Damian Yerrick

Jawaban:

232

Saya akan membuat argumen untuk ==

Douglas Crockford yang Anda kutip dikenal karena pendapatnya yang banyak dan seringkali sangat berguna. Sementara saya bersama Crockford dalam kasus khusus ini, layak disebut bukan satu - satunya pendapat. Ada yang lain seperti pencipta bahasa Brendan Eich yang tidak melihat masalah besar dengannya ==. Argumennya sedikit seperti berikut:

JavaScript adalah bahasa yang diketik * dengan perilaku. Segala sesuatu diperlakukan berdasarkan apa yang dapat mereka lakukan dan bukan tipe yang sebenarnya. Inilah sebabnya mengapa Anda dapat memanggil metode array .mappada NodeList atau pada set pilihan jQuery. Itu juga mengapa Anda dapat melakukan 3 - "5"dan mendapatkan sesuatu yang bermakna kembali - karena "5" dapat bertindak seperti angka.

Saat Anda melakukan ==kesetaraan, Anda membandingkan konten variabel dan bukan jenisnya . Berikut adalah beberapa kasus di mana ini berguna:

  • Membaca nomor dari pengguna - baca .valueelemen input di DOM? Tidak masalah! Anda tidak harus mulai melemparkannya atau mengkhawatirkan tipenya - Anda bisa ==langsung memasukkannya ke angka dan mendapatkan sesuatu yang berarti kembali.
  • Perlu memeriksa "keberadaan" dari variabel yang dideklarasikan? - Anda dapat == nullmelakukannya karena secara perilaku nullmewakili tidak ada apa pun di sana dan tidak terdefinisi juga tidak memiliki apa pun di sana.
  • Perlu memeriksa apakah Anda mendapat input yang berarti dari pengguna? - periksa apakah input salah dengan ==argumen, itu akan memperlakukan kasus pengguna tidak memasukkan apa pun atau hanya ruang putih untuk Anda yang mungkin apa yang Anda butuhkan.

Mari kita lihat contoh-contoh Crockford dan jelaskan secara perilaku:

'' == '0'           // got input from user vs. didn't get input - so false
0 == ''             // number representing empty and string representing empty - so true
0 == '0'            // these both behave as the number 0 when added to numbers - so true    
false == 'false'    // false vs got input from user which is truthy - so false
false == '0'        // both can substitute for 0 as numbers - so again true

false == undefined  // having nothing is not the same as having a false value - so false
false == null       // having empty is not the same as having a false value - so false
null == undefined   // both don't represent a value - so true

' \t\r\n ' == 0     // didn't get meaningful input from user vs falsey number - true 

Pada dasarnya, ==dirancang untuk bekerja berdasarkan bagaimana primitif berperilaku dalam JavaScript tidak didasarkan pada apa yang mereka adalah . Meskipun saya pribadi tidak setuju dengan sudut pandang ini, pasti ada gunanya melakukannya - terutama jika Anda mengambil paradigma ini untuk memperlakukan tipe berdasarkan perilaku bahasa secara luas.

* beberapa mungkin lebih suka mengetik struktural nama yang lebih umum tetapi ada perbedaan - tidak benar-benar tertarik membahas perbedaan di sini.

Benjamin Gruenbaum
sumber
8
Ini adalah jawaban yang bagus, dan saya menggunakan ketiga kasus penggunaan 'untuk ==' Anda. # 1 & # 3 sangat berguna.
Chris Cirefice
224
Masalahnya ==bukan karena tidak ada perbandingan yang berguna , aturannya mustahil untuk diingat sehingga Anda hampir dijamin untuk membuat kesalahan. Misalnya: "Perlu memeriksa apakah Anda mendapat input yang berarti dari pengguna?", Tetapi '0' adalah input yang bermakna dan '0'==falsebenar. Jika Anda menggunakan ===Anda harus berpikir secara eksplisit tentang hal itu dan Anda tidak akan membuat kesalahan.
Timmmm
44
"aturannya tidak mungkin untuk diingat" <== ini adalah satu hal yang membuatku takut melakukan sesuatu yang "bermakna" dalam Javascript. (Dan mengapung matematika yang mengarah ke masalah dalam latihan calc dasar)
WernerCD
9
The 3 - "5"contoh menimbulkan titik baik sendiri: bahkan jika Anda secara eksklusif menggunakan ===untuk perbandingan, itu hanya cara variabel bekerja di Javascript. Tidak ada cara untuk menghindarinya sepenuhnya.
Jarett Millard
23
@Timmmm note Saya bermain sebagai pendukung iblis di sini. Saya tidak menggunakan ==kode saya sendiri, saya merasa ini anti-pola dan saya sepenuhnya setuju bahwa algoritma kesetaraan abstrak sulit untuk diingat. Apa yang saya lakukan di sini adalah membuat argumen yang dibuat orang untuk itu.
Benjamin Gruenbaum
95

Ternyata jQuery menggunakan konstruk

if (someObj == null) {
  // do something
}

secara ekstensif, sebagai singkatan untuk kode yang setara:

if ((someObj === undefined) || (someObj === null))  {
  // do something
}

Ini adalah konsekuensi dari Spesifikasi Bahasa ECMAScript § 11.9.3, Algoritma Perbandingan Kesetaraan Abstrak , yang menyatakan, antara lain, bahwa

1.  If Type(x) is the same as Type(y), then  
    a.  If Type(x) is Undefined, return true.  
    b.  If Type(x) is Null, return true.

dan

2.  If x is null and y is undefined, return true.
3.  If x is undefined and y is null, return true.

Teknik khusus ini cukup umum sehingga JSHint memiliki bendera yang dirancang khusus untuk itu.

Robert Harvey
sumber
10
Tidak adil menjawab pertanyaan Anda sendiri. Saya ingin menjawab ini :) == null or undefinedadalah satu-satunya tempat di mana saya tidak menggunakan ===atau!==
plve
26
Agar adil, jQuery bukanlah basis kode model. Setelah membaca sumber jQuery beberapa kali ini adalah salah satu basis kode paling tidak favorit saya dengan banyak terner bersarang, bit tidak jelas, bersarang, dan hal-hal yang seharusnya saya hindari dalam kode nyata. Jangan mengambil kata-kata saya untuk itu - baca saja github.com/jquery/jquery/tree/master/src lalu bandingkan dengan Zepto yang merupakan klon jQuery: github.com/madrobby/zepto/tree/master/src
Benjamin Gruenbaum
4
Perhatikan juga bahwa Zepto tampaknya default ke ==dan hanya digunakan ===dalam kasus-kasus di mana diperlukan: github.com/madrobby/zepto/blob/master/src/event.js
Hey
2
@Hey bersikap adil Zepto juga bukan basis kode model - ini terkenal karena menggunakan __proto__dan pada gilirannya memaksanya hampir satu per satu ke dalam spesifikasi bahasa untuk menghindari melanggar situs web seluler.
Benjamin Gruenbaum
2
@BenjaminGruenbaum yang tidak menilai menyerukan kualitas basis kode mereka, hanya menunjukkan bahwa proyek yang berbeda mengikuti konvensi yang berbeda.
Hei,
15

Memeriksa nilai untuk nullatau undefinedadalah satu hal, seperti yang telah dijelaskan secara melimpah.

Ada hal lain, di mana ==bersinar:

Anda dapat mendefinisikan perbandingan dari >=seperti itu (orang biasanya mulai dari >tetapi saya menemukan ini lebih elegan):

  • a > b <=> a >= b && !(b >= a)
  • a == b <=> a >= b && b >= a
  • a < bdan a <= bdibiarkan sebagai latihan untuk pembaca.

Seperti yang kita ketahui, dalam JavaScript "3" >= 3dan "3" <= 3, dari mana Anda dapatkan 3 == "3". Anda dapat menegaskan bahwa ini adalah ide yang mengerikan untuk memungkinkan penerapan perbandingan antara string dan angka dengan menguraikan string. Tetapi mengingat bahwa ini adalah cara kerjanya, ==benar - benar cara yang tepat untuk mengimplementasikan hubungan operator itu.

Jadi hal yang benar-benar baik ==adalah konsisten dengan semua hubungan lain. Dengan kata lain, jika Anda menulis ini:

function compare(a, b) {
  if (a > b) return 1;
  if (a < b) return -1;
  return 0;
}

Anda ==sudah menggunakan secara implisit .

Sekarang untuk pertanyaan yang cukup terkait: Apakah itu pilihan yang buruk untuk mengimplementasikan perbandingan angka dan string cara penerapannya? Terlihat dalam isolasi, tampaknya hal yang agak bodoh untuk dilakukan. Tetapi dalam konteks bagian lain dari JavaScript dan DOM, ini relatif pragmatis, mengingat:

  • atribut selalu bersifat string
  • kunci selalu berupa string (kasus penggunaannya adalah bahwa Anda menggunakan a Objectuntuk memiliki peta yang jarang dari int ke nilai)
  • input pengguna dan nilai kontrol formulir selalu berupa string (bahkan jika sumbernya cocok input[type=number])

Untuk sejumlah alasan, masuk akal untuk membuat string berperilaku seperti angka ketika dibutuhkan. Dan dengan asumsi bahwa perbandingan string dan penggabungan string memiliki operator yang berbeda (misalnya ::untuk menyimpulkan dan metode untuk membandingkan (di mana Anda dapat menggunakan semua jenis parameter mengenai sensitivitas huruf dan apa yang tidak)), ini sebenarnya akan menjadi kurang berantakan. Tapi operator kelebihan ini mungkin sebenarnya dari mana "Java" dalam "JavaScript" berasal;)

back2dos
sumber
4
Agar adil >=tidak benar-benar transitif. Sangat mungkin di JS yang tidak a > batau a < btidak b == a(misalnya NaN:).
Benjamin Gruenbaum
8
@BenjaminGruenbaum: Itu seperti mengatakan +tidak benar-benar komutatif, karena NaN + 5 == NaN + 5tidak berlaku. Intinya adalah bahwa >=bekerja dengan nilai-nilai angka yang ==bekerja secara konsisten. Seharusnya tidak mengejutkan bahwa "bukan angka" pada dasarnya bukan angka-ish;)
back2dos
4
Jadi perilaku buruk ==konsisten dengan perilaku buruk >=? Hebat, sekarang saya berharap ada >==...
Eldritch Conundrum
2
@ ElldCitchundrum: Seperti yang saya coba jelaskan, perilaku >=agak konsisten dengan sisa bahasa / API standar. Dalam totalitasnya, JavaScript mengelola lebih dari jumlah bagian uniknya. Jika Anda menginginkan >==, apakah Anda juga menginginkan yang ketat +? Dalam praktiknya, banyak dari keputusan ini membuat banyak hal menjadi lebih mudah. Jadi saya tidak akan terburu-buru menilai mereka miskin.
back2dos
2
@ ElldCitchundrum: Sekali lagi: operator hubungan dimaksudkan untuk membandingkan nilai numerik, di mana satu operan mungkin sebenarnya adalah string. Untuk jenis operan yang >=bermakna, ==sama-sama bermakna - itu saja. Tidak ada yang mengatakan Anda harus membandingkan [[]]dengan false. Dalam bahasa seperti C hasil tingkat omong kosong ini adalah perilaku yang tidak terdefinisi. Perlakukan saja dengan cara yang sama: jangan lakukan itu. Dan kamu akan baik-baik saja. Anda juga tidak perlu mengingat aturan sihir apa pun. Dan kemudian itu sebenarnya agak lurus ke depan.
back2dos
8

Sebagai ahli matematika profesional, saya melihat dalam operator kesamaan Javscript == (juga disebut "perbandingan abstrak", "kesetaraan longgar" ) upaya untuk membangun hubungan ekivalensi antara entitas, yang termasuk menjadi refleksif , simetris , dan transitif . Sayangnya, dua dari tiga sifat dasar ini gagal:

==tidak refleksif :

A == A mungkin salah, mis

NaN == NaN // false

==tidak transitif :

A == Bdan B == Cbersama-sama tidak menyiratkan A == C, mis

'1' == 1 // true
1 == '01' // true
'1' == '01' // false

Hanya properti simetrik yang bertahan:

A == Bmenyiratkan B == A, pelanggaran mana yang mungkin tidak terpikirkan dalam kasus apa pun dan akan menyebabkan pemberontakan yang serius;)

Mengapa hubungan kesetaraan penting?

Karena itulah jenis hubungan yang paling penting dan lazim, didukung oleh banyak contoh dan aplikasi. Aplikasi yang paling penting adalah dekomposisi entitas menjadi kelas kesetaraan , yang dengan sendirinya merupakan cara yang sangat mudah dan intuitif untuk memahami hubungan. Dan kegagalan untuk menjadi ekuivalensi mengarah pada kurangnya kelas ekivalensi, yang pada gilirannya mengarah pada kurangnya intuisi dan kompleksitas yang tidak perlu yang terkenal.

Mengapa ini merupakan ide yang mengerikan untuk menulis ==untuk hubungan yang tidak setara?

Karena itu merusak keakraban dan intuisi kita, karena secara harfiah ada hubungan yang menarik dari kesamaan, kesetaraan, kongruensi, isomorfisme, identitas dll adalah kesetaraan.

Jenis konversi

Alih-alih mengandalkan kesetaraan intuitif, JavaScript memperkenalkan konversi jenis:

Operator kesetaraan mengubah operan jika tidak dari jenis yang sama, kemudian menerapkan perbandingan yang ketat.

Tetapi bagaimana definisi jenis konversi? Melalui serangkaian aturan rumit dengan banyak pengecualian?

Mencoba membangun relasi kesetaraan

Boolean. Jelas truedan falsetidak sama dan harus di kelas yang berbeda.

Angka Untungnya, kesetaraan angka sudah didefinisikan dengan baik, di mana dua angka yang berbeda tidak pernah berada dalam kelas ekivalensi yang sama. Dalam matematika, itu. Dalam JavaScript gagasan angka agak berubah bentuk melalui kehadiran yang lebih eksotis -0, Infinitydan -Infinity. Intuisi matematika kami menyatakan bahwa 0dan -0harus di kelas yang sama (pada kenyataannya -0 === 0adalah true), sedangkan masing-masing infinities adalah kelas terpisah.

Bilangan dan Boolean. Mengingat nomor kelas, di mana kita meletakkan boolean? falsemenjadi mirip dengan 0, sedangkan truemenjadi serupa 1tetapi tidak ada nomor lain:

true == 1 // true
true == 2 // false

Apakah ada logika di sini untuk truedisatukan 1? Diakui 1dibedakan, tetapi begitu juga -1. Saya pribadi tidak melihat alasan untuk mengkonversi trueke 1.

Dan itu menjadi lebih buruk:

true + 2 // 3
true - 1 // 0

Jadi truememang diubah menjadi di 1antara semua angka! Apakah ini logis? Apakah ini intuitif? Jawabannya dibiarkan sebagai latihan;)

Tapi bagaimana dengan ini:

1 && true // true
2 && true // true

Satu-satunya boolean xdengan x && truemakhluk trueadalah x = true. Yang membuktikan bahwa keduanya 1dan 2(dan nomor lain selain 0) berkonversi ke true! Apa yang ditunjukkannya adalah bahwa konversi kami gagal dalam properti penting lainnya - yaitu penambangan . Berarti bahwa dua entitas yang berbeda dapat dikonversi ke entitas yang sama. Yang dengan sendirinya tidak harus menjadi masalah besar. Masalah besar muncul ketika kita menggunakan konversi ini untuk menggambarkan hubungan "kesamaan" atau "kesetaraan longgar" dari apa pun yang kita ingin menyebutnya. Tapi satu hal yang jelas - itu tidak akan menjadi hubungan ekivalensi dan tidak akan dijelaskan secara intuitif melalui kelas ekivalensi.

Tetapi bisakah kita melakukan yang lebih baik?

Setidaknya secara matematis - pasti ya! Hubungan kesetaraan sederhana antara boolean dan angka hanya dapat dibangun dengan falsedan 0berada di kelas yang sama. Jadi false == 0akan menjadi satu-satunya kesetaraan longgar non-sepele.

Bagaimana dengan string?

Kita dapat memangkas string dari spasi putih di awal dan akhir untuk mengkonversi ke angka, juga kita bisa mengabaikan nol di depan:

'   000 ' == 0 // true
'   0010 ' == 10 // true

Jadi kita mendapatkan aturan sederhana untuk string - trim spasi putih dan nol di depan. Entah kita mendapatkan angka atau string kosong, dalam hal ini kita mengkonversi ke angka itu atau nol. Atau kami tidak mendapatkan nomor, dalam hal ini kami tidak mengonversi sehingga tidak ada hubungan baru.

Dengan cara ini kita benar-benar bisa mendapatkan hubungan kesetaraan yang sempurna pada set boolean, angka, dan string! Kecuali itu ... Desainer JavaScript jelas memiliki pendapat lain:

' ' == '' // false

Jadi dua string yang keduanya dikonversi menjadi 0tiba-tiba tidak serupa! Kenapa atau mengapa? Menurut aturan, string secara longgar sama persis ketika mereka benar-benar sama! Tidak hanya aturan ini memecah transitivitas seperti yang kita lihat, tetapi juga berlebihan! Apa gunanya membuat operator lain ==agar benar-benar identik dengan yang lain ===?

Kesimpulan

Operator kesetaraan longgar ==bisa sangat berguna jika mematuhi beberapa hukum matematika dasar. Tapi sayangnya tidak ada manfaatnya.

Dmitri Zaitsev
sumber
Bagaimana dengan NaN? Selain itu, kecuali jika format angka tertentu diberlakukan untuk perbandingan dengan string, perbandingan string yang tidak intuitif atau non-transitivitas harus dihasilkan.
Solomon Ucko
@SolomonUcko NaNbertindak sebagai warga negara yang buruk :-). Transivity dapat dan harus ditegakkan untuk perbandingan kesetaraan, intuitif atau tidak.
Dmitri Zaitsev
7

Ya, saya telah menemukan kasus penggunaan untuk itu, yaitu ketika Anda membandingkan kunci dengan nilai numerik:

for (var key in obj) {
    var some_number = foo(key, obj[key]);  // or whatever -- this is just an example
    if (key == some_number) {
        blah();
    }
}

Saya pikir itu jauh lebih alami untuk melakukan perbandingan key == some_numberdaripada sebagai Number(key) === some_numberatau sebagai key === String(some_number).

Mehrdad
sumber
3

Saya menemukan aplikasi yang sangat berguna hari ini. Jika Anda ingin membandingkan angka empuk, seperti 01bilangan bulat normal, ==berfungsi dengan baik. Sebagai contoh:

'01' == 1 // true
'02' == 1 // false

Ini menghemat Anda menghapus 0 dan mengkonversi ke integer.

Jon Snow
sumber
4
Saya cukup yakin cara 'benar' dalam melakukan ini '04'-0 === 4, atau mungkinparseInt('04', 10) === 4
ratbum
Saya tidak sadar Anda bisa melakukan ini.
Jon Snow
7
Aku mendapatkan banyak.
Jon Snow
1
@ratbum atau+'01' === 1
Eric Lagergren
1
'011' == 011 // falsedalam mode non-ketat, dan SyntaxError dalam mode ketat. :)
Brian S
3

Saya tahu ini adalah jawaban yang terlambat, tetapi tampaknya ada beberapa kemungkinan kebingungan tentang nulldan undefined, yang IMHO adalah yang membuat ==kejahatan, lebih dari kurangnya transitivitas, yang cukup buruk. Mempertimbangkan:

p1.supervisor = 'Alice';
p2.supervisor = 'None';
p3.supervisor = null;
p4.supervisor = undefined;

Apa artinya ini?

  • p1 memiliki penyelia yang bernama "Alice."
  • p2 memiliki penyelia yang namanya "Tidak Ada."
  • p3secara eksplisit, tegas, tidak memiliki pengawas .
  • p4mungkin atau mungkin memiliki penyelia. Kita tidak tahu, kita tidak peduli, kita tidak seharusnya tahu (masalah privasi?), Karena itu bukan urusan kita.

Saat Anda menggunakan ==Anda sedang melakukan conflating nulldan undefinedmana yang sepenuhnya tidak tepat. Kedua istilah tersebut memiliki arti yang sangat berbeda! Mengatakan bahwa saya tidak memiliki penyelia hanya karena saya menolak memberi tahu Anda siapa penyelia saya yang salah!

Saya mengerti ada programmer yang tidak peduli tentang perbedaan antara nulldan undefinedatau memilih untuk menggunakan istilah ini secara berbeda. Dan jika dunia Anda tidak menggunakan nulldan undefineddengan benar, atau Anda ingin memberikan interpretasi Anda sendiri untuk istilah-istilah ini, maka jadilah itu. Saya pikir itu bukan ide yang bagus.

Ngomong-ngomong, aku tidak punya masalah dengan nulldan undefinedkeduanya menjadi palsu! Tidak apa-apa untuk mengatakannya

if (p.supervisor) { ... }

dan kemudian nulldan undefinedakan menyebabkan kode yang memproses pengawas dilewati. Itu benar, karena kita tidak tahu atau tidak memiliki penyelia. Semuanya bagus. Tetapi kedua situasi itu tidak sama . Inilah sebabnya mengapa ==salah. Sekali lagi, hal-hal dapat menjadi palsu dan digunakan dalam arti mengetik bebek, yang sangat bagus untuk bahasa yang dinamis. Ini adalah JavaScript yang tepat, Pythonic, Rubyish, dll. Tetapi sekali lagi, hal-hal ini TIDAK setara.

Dan jangan mulai pada non-transitivitas: "0x16" == 10, 10 == "10"tapi tidak "10" == "0x16". Ya, JavaScript jenisnya lemah. Ya, itu pemaksaan. Tapi paksaan seharusnya tidak pernah berlaku untuk kesetaraan.

Omong-omong, Crockford memang memiliki pendapat yang kuat. Tapi tahukah Anda? Dia benar di sini!

FWIW Saya mengerti bahwa ada, dan secara pribadi saya mengalami situasi di mana ==nyaman! Seperti mengambil input string untuk angka dan, katakanlah, membandingkan dengan 0. Namun, ini adalah hack. Anda memiliki kemudahan sebagai tradeoff untuk model dunia yang tidak akurat.

TL; DR: kepalsuan adalah konsep yang hebat. Seharusnya tidak mencakup kesetaraan.

Ray Toal
sumber
Terima kasih telah menunjukkan situasi yang berbeda :) Namun, Anda hilang p5... satu situasi di typeof(p5.supervisor) === typeof(undefined)mana pengawas bahkan tidak ada sebagai konsep: D
TheCatWhisperer