Typeof di JavaScript sebenarnya sangat kompleks. Dapat digunakan untuk melakukan banyak hal, tetapi juga memiliki banyak perilaku aneh. Artikel ini mencantumkan berbagai kegunaannya, dan juga menunjukkan masalah dan solusi yang ada.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FOperators%2Ftypeof
> jenis tidak terdefinisi
'belum diartikan'
> typeof null // bug terkenal
'obyek'
> jenis benar
'boolean'
> tipe 123
'nomor'
> ketik "abc"
'rangkaian'
> jenis fungsi() {}
'fungsi'
> jenis {}
'obyek'
> jenis []
'obyek'
> jenis Variabel yang tidak diketahui
'belum diartikan'
1. Periksa apakah suatu variabel ada dan mempunyai nilai.
typeof akan mengembalikan "tidak terdefinisi" dalam dua situasi: ketika suatu variabel tidak dideklarasikan, dan ketika nilai suatu variabel tidak ditentukan.
> typeof undeclaredVariable === "tidak terdefinisi" benar > var variabel yang dideklarasikan; > typeof yang dideklarasikanVariable 'tidak terdefinisi' > typeof tidak terdefinisi 'tidak terdefinisi'
Ada cara lain untuk mendeteksi apakah suatu nilai tidak ditentukan:
> nilai var = tidak terdefinisi; > nilai === tidak terdefinisi benar
Namun jika metode ini digunakan pada variabel yang tidak dideklarasikan, pengecualian akan diberikan, karena hanya typeof yang dapat mendeteksi variabel yang tidak dideklarasikan secara normal tanpa melaporkan kesalahan:
> undeclaredVariable === Kesalahan Referensi yang tidak ditentukan: undeclaredVariable tidak ditentukan
Catatan: Variabel yang tidak diinisialisasi, parameter formal tanpa parameter yang diteruskan, dan properti yang tidak ada tidak akan mengalami masalah di atas, karena selalu dapat diakses dan nilainya selalu tidak ditentukan:
> var dideklarasikanVariable; > dideklarasikanVariable === tidak terdefinisi benar > (fungsi (x) { return x === tidak terdefinisi }()) benar > ({}).foo === tidak terdefinisi benar
Catatan Penerjemah: Oleh karena itu, jika Anda ingin mendeteksi keberadaan variabel global yang mungkin tidak dideklarasikan, Anda juga bisa menggunakan if(window.maybeUndeclaredVariable){}
Masalah: typeof rumit untuk menyelesaikan tugas seperti itu.
Solusi: Operasi semacam ini tidak terlalu umum, sehingga beberapa orang merasa tidak perlu mencari solusi yang lebih baik. Namun mungkin seseorang akan mengusulkan operator khusus:
> mendefinisikan variabel yang tidak dideklarasikan salah > var variabel yang dideklarasikan; > mendefinisikan variabel yang dideklarasikan salah
Atau, mungkin kita juga memerlukan operator yang mendeteksi apakah suatu variabel dideklarasikan:
> mendeklarasikan undeclaredVariable salah > var mendeklarasikanVariable; > mendeklarasikanVariable benar
Catatan Penerjemah: Di Perl, operator yang ditentukan di atas setara dengan yang ditentukan(), dan operator yang dideklarasikan di atas setara dengan yang ada().
2. Tentukan apakah suatu nilai tidak sama dengan tidak terdefinisi atau nol.
Masalah: Jika Anda ingin memeriksa apakah suatu nilai telah ditentukan (nilainya tidak terdefinisi atau nol), maka Anda menemukan salah satu kebiasaan paling terkenal dari typeof (dianggap sebagai bug): typeof null mengembalikan "objek":
> ketik 'objek' nol
Catatan Penerjemah: Ini hanya dapat dikatakan sebagai bug dalam implementasi JavaScript asli, dan ini adalah bagaimana standar tersebut sekarang distandarisasi. V8 setelah direvisi dan diimplementasikan typeof null === "null", tetapi pada akhirnya terbukti tidak layak http: //wiki .ecmascript.org/doku.php?id=harmony:typeof_null
Solusi: Jangan gunakan typeof untuk tugas ini, gunakan fungsi seperti ini:
fungsi Didefinisikan(x) { kembalikan x !== null && x !== tidak ditentukan }
Kemungkinan lain adalah dengan memperkenalkan "operator nilai default", di mana ekspresi berikut mengembalikan defaultValue jika myValue tidak ditentukan:
Nilai saya ??
Ekspresi di atas setara dengan:
(nilaiku !== tidak terdefinisi && nilaiku !== null) ?
Atau:
Nilaiku ??= Nilai default
Sebenarnya, ini merupakan penyederhanaan dari pernyataan berikut:
Nilaiku = Nilaiku ?? Nilai default
Saat Anda mengakses properti bertingkat, seperti bar, Anda mungkin memerlukan bantuan operator ini:
obj.foo.bar
Jika obj atau obj.foo tidak terdefinisi, ekspresi di atas akan memunculkan pengecualian. Operator.?? mengizinkan ekspresi di atas mengembalikan nilai pertama yang ditemukan saat melintasi properti lapis demi lapis.
obj.??foo.??bar
Ekspresi di atas setara dengan:
(obj === tidak terdefinisi || obj === null) ? obj : (obj.foo === tidak terdefinisi || obj.foo === null) ?
3. Membedakan nilai objek dan nilai primitif
Fungsi berikut menguji apakah x adalah nilai objek:
function isObject(x) { return (tipe x === "fungsi" || (tipe x === "objek" && x !== null) }
Masalah: Deteksi di atas rumit karena typeof menganggap fungsi dan objek sebagai tipe yang berbeda, dan typeof null mengembalikan "objek".
Solusi: Metode berikut juga sering digunakan untuk mendeteksi nilai objek:
fungsi isObject2(x) { kembalikan x === Objek(x };
Peringatan: Anda mungkin berpikir bahwa Anda dapat menggunakan instanceof Object untuk mendeteksi di sini, tetapi instanceof menentukan hubungan instance dengan menggunakan prototipe suatu objek, lalu bagaimana dengan objek tanpa prototipe:
> var obj = Objek.buat(null); > Objek.getPrototypeOf(obj) nol
obj memang sebuah objek, tapi itu bukan turunan dari nilai apa pun:
> typeof obj 'objek' > obj instanceof Objek salah
Dalam praktiknya, Anda mungkin jarang menjumpai benda seperti itu, namun benda itu memang ada dan ada kegunaannya.
Catatan Penerjemah: Objek.prototipe adalah objek yang ada secara default dan tidak memiliki prototipe.
>Object.getPrototypeOf(Object.prototype)null>typeof Object.prototype'object'>Object.prototype instanceof Object false
4.Apa jenis nilai primitif?
typeof adalah cara terbaik untuk memeriksa tipe nilai primitif.
> tipe "abc" 'string' > tipe tidak terdefinisi 'tidak terdefinisi'
Masalah: Anda harus menyadari perilaku aneh typeof null.
> typeof null // Hati-hati! 'objek'
Solusi: Fungsi berikut dapat memperbaiki masalah ini (hanya untuk kasus penggunaan ini).
function getPrimitiveTypeName(x) { var typeName = typeof x; switch(typeName) { case "tidak terdefinisi": case "boolean": case "number": case "string": return typeName; = null) { return "null"; } default: // Tidak ada penilaian sebelumnya yang lolos throw new TypeError("Parameter bukan nilai primitif: "+x } }
Solusi yang lebih baik: mengimplementasikan fungsi getTypeName(), yang selain mengembalikan tipe nilai asli, juga dapat mengembalikan atribut internal [[Class]] dari nilai objek. Berikut adalah cara mengimplementasikan fungsi ini (Catatan Penerjemah: jQuery $.type adalah implementasi seperti itu)
5. Apakah suatu nilai tertentu merupakan suatu fungsi
typeof dapat digunakan untuk mendeteksi apakah suatu nilai merupakan suatu fungsi. > typeof function () {} 'function' > typeof Object.prototype.toString 'function'
Pada prinsipnya, instanceof Fungsi juga dapat mendeteksi persyaratan ini. Sekilas, tampaknya metode penulisannya lebih elegan. Namun, browser memiliki keunikan: setiap frame dan jendela memiliki variabel globalnya sendiri objek dilewatkan ke framework lain, instanceof tidak akan berfungsi dengan baik karena kedua framework tersebut memiliki konstruktor yang berbeda Inilah mengapa ada metode Array.isArray() di ECMAScript 5. Alangkah baiknya jika ada metode lintas kerangka untuk memeriksa apakah suatu objek merupakan turunan dari konstruktor tertentu. GetTypeName() di atas adalah solusi yang tersedia , namun mungkin ada solusi yang lebih mendasar.
6. Ikhtisar
Yang disebutkan berikut ini harus menjadi fitur yang paling dibutuhkan dalam JavaScript saat ini, dan dapat menggantikan beberapa fitur fungsional dari tanggung jawab typeof saat ini:
isDefined() (seperti Object.isDefined()): dapat digunakan sebagai fungsi atau operator
isObject()
dapatkanTypeName()
Mekanisme lintas kerangka untuk mendeteksi apakah suatu objek merupakan turunan dari konstruktor tertentu
Kebutuhan untuk memeriksa apakah suatu variabel telah dideklarasikan mungkin tidak memerlukan operatornya sendiri.