Identifikasi tipe dinamis. JavaScript, typeof, tipe dan kelas Kesalahan terkait dengan zona mati sementara

Identifikasi tipe dinamis

Identifikasi Tipe Dinamis (RTTI) memungkinkan Anda menentukan jenis objek selama eksekusi program. Ternyata bermanfaat karena beberapa alasan. Khususnya, dengan menggunakan referensi ke kelas dasar, Anda dapat menentukan secara akurat jenis objek yang dapat diakses melalui referensi ini. Identifikasi tipe dinamis juga memungkinkan Anda memeriksa terlebih dahulu seberapa sukses suatu tipe cast, mencegah pengecualian karena tipe cast yang salah. Selain itu, identifikasi tipe dinamis merupakan komponen utama refleksi.

Untuk mendukung identifikasi tipe dinamis, C# menyediakan tiga kata kunci a: adalah, sebagai dan typeof. Masing-masing kata kunci tersebut dibahas satu per satu di bawah ini.

adalah operator

Tipe spesifik suatu objek dapat ditentukan dengan menggunakan operator is. Di bawah ini adalah bentuk umumnya:

ekspresi adalah tipe

di mana ekspresi menunjukkan ekspresi tunggal yang mendeskripsikan objek yang tipenya sedang diuji. Jika ekspresi bertipe kompatibel atau sama dengan tipe yang diuji, maka hasil operasi ini benar, jika tidak maka salah. Jadi, hasilnya akan benar jika ekspresi tersebut memiliki tipe yang diuji dalam satu bentuk atau lainnya. Operator is mendefinisikan kedua jenis sebagai kompatibel jika keduanya merupakan jenis yang sama atau jika referensi konversi, tinju, atau buka kotak disediakan.

Di bawah ini adalah contoh penggunaan operator is:

Menggunakan Sistem; namespace ConsoleApplication1 ( kelas Tambah ( ) kelas Jumlah: Tambah ( ) kelas Program ( static void Main() ( Tambah a = Tambah baru(); Jumlah s = Jumlah baru(); jika (a adalah Tambah) Console.WriteLine("Variabel a bertipe Tambah"); if (s adalah Jumlah) Console.WriteLine("Tipe variabel s diwarisi dari kelas Tambah"); Console.ReadLine(); ) ) )

Operator sebagai

Terkadang Anda ingin melakukan konversi tipe saat runtime, tetapi tidak memberikan pengecualian jika konversi gagal, yang sangat mungkin dilakukan dengan casting tipe. Operator as melayani tujuan ini, memiliki bentuk umum sebagai berikut:

ekspresi sebagai tipe

di mana ekspresi menunjukkan ekspresi tunggal yang mengkonversi ke tipe tertentu.

Jika hasil konversi tersebut berhasil, maka referensi ke tipe tersebut dikembalikan, jika tidak maka referensi kosong. Operator as hanya dapat digunakan untuk konversi referensi, identitas, boxing, unboxing. Dalam beberapa kasus, operator as dapat menjadi alternatif yang tepat untuk operator is. Sebagai contoh, perhatikan program berikut:

Menggunakan Sistem; namespace ConsoleApplication1 ( class Add ( ) class Sum: Add ( ) class Program ( static void Main() ( Add a = new Add(); Sum s = new Sum(); // Lakukan pengecoran tipe a = s sebagai Add; if (a != null) Console.WriteLine("Konversi berhasil"); else Console.WriteLine("Kesalahan selama konversi");

Hasil dari pelaksanaan program ini adalah konversi yang berhasil.

JavaScript atau JS(disingkat) bukanlah bahasa yang mudah dan pengembang pemula tidak akan langsung mempelajarinya. Pada awalnya mereka mempelajari dasar-dasarnya dan segala sesuatunya tampak penuh warna dan indah. Lebih dalam lagi, array JavaScript, objek, panggilan balik, dan segala sesuatu seperti itu muncul, yang sering kali membuat Anda terkejut.

Dalam JavaScript, penting untuk memeriksa jenis variabel dengan benar. Katakanlah Anda ingin mengetahui apakah suatu variabel adalah array atau objek? Bagaimana cara memeriksanya dengan benar? Dalam kasus khusus ini, ada trik selama verifikasi dan postingan ini akan membahasnya. Mari kita mulai segera.

Memeriksa jenis variabel

Misalnya, Anda perlu memeriksa apakah suatu variabel adalah objek, array, string, atau angka. Anda dapat menggunakan typeof untuk ini, tetapi itu tidak selalu mengatakan yang sebenarnya dan dalam contoh di bawah ini saya akan menunjukkan alasannya.

Saya menulis contoh ini untuk menunjukkan dengan jelas mengapa typeof tidak selalu merupakan pilihan yang tepat.

Var _comparison = ( string: "string", int: 99, float: 13.555, objek: (halo: "halo"), array: new Array(1, 2, 3) ); // Mengembalikan array dengan kunci objek var _objKeys = Object.keys(_comparison); untuk(var saya = 0; saya<= _objKeys.length - 1; i++) { // выведем в консоль тип каждой переменной console.log(typeof _comparson[_objKeys[i]]); }

Hasil eksekusi kode:

Objek objek nomor string

Benar? - Tentu saja tidak. Ada dua masalah. Masing-masing akan dijelaskan secara rinci dan solusi yang diusulkan.

Masalah pertama: bilangan float, keluaran sebagai bilangan

Comparison.float bukanlah angka dan sebagai pengganti angka seharusnya berupa float (angka floating point). Untuk mengatasinya, Anda dapat membuat fungsi dengan tanda centang seperti pada kode di bawah ini.

Var_floatNumber = 9,22; var _notFloatNumber = 9; konsol.log(isFloat(_floatNumber)); konsol.log(isFloat(_notFloatNumber)); konsol.log(isFloat("")); fungsi isFloat(n)( Nomor kembalian(n) === n && n % 1 !== 0; )

Fungsi isFloat() memeriksa apakah semua nilai adalah floating point. Pertama, diperiksa apakah variabelnya sama N bilangan (Bilangan(n) === n) dan jika ya, maka dilakukan pengecekan lagi untuk pembagian dengan sisa dan jika terdapat sisa, maka boolean ( BENAR atau PALSU) hasil (n % 1 !== 0).

Dalam contoh di atas, ia kembali BENAR, PALSU Dan PALSU. Arti pertama adalah mengambang ketik, yang kedua bukan - itu angka biasa dan yang terakhir hanyalah string kosong yang tidak sesuai aturan.

Masalah kedua: array didefinisikan sebagai objek

Pada contoh pertama, array ditampilkan sebagai objek dan ini tidak terlalu bagus, karena terkadang Anda perlu menggunakan tipe ini dan tidak ada yang lain.

Ada beberapa cara untuk memeriksa apakah suatu variabel bertipe array.

Opsi pertama (pilihan bagus). Kami memeriksa apakah data termasuk dalam array menggunakan instanceof().

Var data = array baru("halo", "dunia"); var isArr = contoh data Array;

Opsi kedua (pilihan bagus). Metode Array.isArray() mengembalikan nilai boolean yang akan bergantung pada apakah variabelnya berupa array atau bukan ().

Var data = array baru("halo", "dunia"); var isArr = Array.isArray(data);

Opsi ketiga (yang terbaik, tapi panjang). Untuk kenyamanan, Anda dapat menjadikan metode ini sebagai fungsi. Menggunakan Object yang kita lakukan. Jika hasil Object.prototype.toString.call(data) tidak sama, maka variabel tersebut bukan array ().

Var data = array baru("halo", "dunia"); var isArr = Objek.prototipe.toString.call(data) == ""; konsol.log(isArr);

Hasil terakhir berupa fungsi kemudahan:

Fungsi isArray(data) ( return Object.prototype.toString.call(data) == "" )

Sekarang Anda dapat memanggil fungsi isArray() dan menetapkan array atau sesuatu yang lain sebagai argumen dan melihat hasilnya.

Kata penutup

Rekamannya ternyata cukup besar dari perkiraan semula. Namun saya senang dengan hal ini karena cukup ringkas dan jelas menjelaskan kesulitan saat memeriksa variabel dalam JavaScript dan cara menyiasatinya.

Jika Anda masih memiliki pertanyaan, tuliskan di bawah entri ini. Saya akan dengan senang hati membantu.

Operator jenis mengembalikan string yang menunjukkan jenis operan.

Sintaksis

Operan mengikuti operator typeof:

Jenis operan

Pilihan

operan adalah ekspresi yang mewakili suatu objek atau primitif yang tipenya akan dikembalikan.

Keterangan

Tabel berikut mencantumkan kemungkinan nilai kembalian typeof. Informasi lebih lanjut tentang tipe dan primitif dapat ditemukan di halaman.

Contoh

// Angka tipe 37 === "angka"; typeof 3.14 === "angka"; typeof(42) === "angka"; typeof Math.LN2 === "angka"; typeof Infinity === "angka"; typeof NaN === "angka"; // meskipun ini adalah "Bukan-A-Nomor" typeof Number(1) === "number"; // jangan pernah gunakan entri ini! // Tipe string dari "" === "string"; ketik "bla" === "string"; ketik "1" === "string"; // perhatikan bahwa nomor di dalam string masih bertipe string typeof (typeof 1) === "string"; // typeof akan selalu mengembalikan string dalam hal ini typeof String("abc") === "string"; // jangan pernah gunakan entri ini! // Boolean typeof true === "boolean"; typeof false === "boolean"; typeof Boolean(benar) === "boolean"; // jangan pernah gunakan entri ini! // Simbol typeof Simbol() === "simbol" typeof Simbol("foo") === "simbol" typeof Simbol.iterator === "simbol" // Jenis tidak terdefinisi tidak terdefinisi === "tidak terdefinisi"; typeof dideklarasikanButUndefinisiVariable === "tidak terdefinisi"; typeof undeclaredVariable === "tidak terdefinisi"; // Objek typeof (a: 1) === "objek"; // gunakan Array.isArray atau Object.prototype.toString.call // untuk membedakan antara objek biasa dan array typeof === "object"; typeof new Date() === "objek"; // Hal berikut ini menyebabkan kesalahan dan masalah. Jangan gunakan itu! typeof new Boolean(true) === "objek"; typeof Nomor baru(1) === "objek"; typeof new String("abc") === "objek"; // Fungsi typeof function() () === "fungsi"; typeof kelas C() === "fungsi"; typeof Math.sin === "fungsi";

batal

// Ini telah didefinisikan sejak lahirnya JavaScript typeof null === "object";

Pada implementasi pertama JavaScript, nilai diwakili oleh tipe tag dan pasangan nilai. Jenis tag untuk objek adalah 0. null direpresentasikan sebagai penunjuk nol (0x00 di sebagian besar platform). Oleh karena itu, tipe tag untuk null adalah null, sehingga nilai kembalian dari typeof adalah tiruan. ()

Perbaikan diusulkan dalam ECMAScript (melalui penonaktifan) tetapi ditolak. Ini akan menghasilkan typeof null === "null" .

Menggunakan operator baru

// Semua fungsi konstruktor yang dibuat dengan "baru" akan bertipe "objek" var str = new String("String"); var nomor = Nomor baru(100); ketik str; // Mengembalikan tipe nomor "objek"; // Mengembalikan "objek" // Namun ada pengecualian untuk konstruktor Fungsi var func = new Function(); jenis fungsi; // Mengembalikan "fungsi"

Ekspresi Reguler

Ekspresi reguler yang dapat dipanggil merupakan tambahan non-standar di beberapa browser.

Ketik /s/ === "fungsi"; // Chrome 1-12 Tidak mematuhi ECMAScript 5.1 typeof /s/ === "object"; // Firefox 5+ Sesuai dengan ECMAScript 5.1

Kesalahan terkait dengan zona mati sementara

Sebelum ECMAScript 2015, operator typeof dijamin mengembalikan string untuk operan apa pun yang dipanggil. Hal ini berubah dengan penambahan deklarasi let dan const non-hoisting dengan cakupan blok. Sekarang, jika variabel dideklarasikan dengan let dan const dan typeof dipanggil di blok deklarasi variabel, tetapi sebelum deklarasi, maka ReferrenceError akan muncul. Perilakunya berbeda dengan variabel yang tidak dideklarasikan, yang mana typeof akan mengembalikan "tidak terdefinisi". Variabel dengan cakupan blok memiliki "zona mati sementara" yang berlangsung dari awal blok hingga variabel dideklarasikan. Di zona ini, upaya untuk mengakses variabel memunculkan pengecualian.

Typeof undeclaredVariable === "tidak terdefinisi"; typeof newLetVariable; biarkan newLetVariable; // Jenis Kesalahan Referensi dari VariabelConst baru; const newConstVariable = "halo"; // Kesalahan Referensi

Pengecualian

Di semua browser saat ini, terdapat objek host non-standar document.all, yang bertipe Tidak Terdefinisi.

Typeof document.all === "tidak terdefinisi";

Meskipun spesifikasinya mengizinkan nama jenis khusus untuk objek eksotik non-standar, spesifikasi ini mengharuskan nama-nama ini berbeda dari yang telah ditentukan sebelumnya. Situasi di mana document.all bertipe tidak terdefinisi harus dianggap sebagai pelanggaran aturan yang luar biasa.

Spesifikasi

Spesifikasi Status Komentar
Draf Terbaru ECMAScript (ECMA-262)
Draf
ECMAScript 2015 (Edisi ke-6, ECMA-262)
Definisi "Operator typeof" ada dalam spesifikasi ini.
Standar
Skrip ECMA 5.1 (ECMA-262)
Definisi "Operator typeof" ada dalam spesifikasi ini.
Standar
ECMAScript Edisi ke-3 (ECMA-262)
Definisi "Operator typeof" ada dalam spesifikasi ini.
Standar
ECMAScript Edisi Pertama (ECMA-262)
Definisi "Operator typeof" ada dalam spesifikasi ini.
Standar Definisi awal. Diimplementasikan dalam JavaScript 1.1

Kompatibilitas peramban

Perbarui data kompatibilitas di GitHub

KomputerSelulerpelayan
kromTepianFirefoxPenjelajah InternetOperaSafaritampilan web AndroidChrome untuk AndroidFirefox untuk AndroidOpera untuk AndroidSafari di iOSSamsung InternetNode.js
jeniskrom Dukungan penuh 1 Tepian Dukungan penuh 12 Firefox Dukungan penuh 1 YAITU. Dukungan penuh 3 Opera Dukungan penuh YaSafari Dukungan penuh YaTampilan Web Android Dukungan penuh 1 Chrome Android Dukungan penuh 18 Firefox Android Dukungan penuh 4 Opera Android Dukungan penuh YaSafari iOS Dukungan penuh YaSamsung InternetAndroid Dukungan penuh 1.0 nodejs Dukungan penuh Ya

Legenda

Dukungan penuh Dukungan penuh

Catatan khusus IE

Di IE 6, 7, dan 8, banyak objek host yang merupakan objek, namun bukan fungsi. Misalnya.

a = (b > 0) && (c + 1 != d); bendera = !(status = 0);

Tabel 14.5. Operator logika

Deskripsi Operator

! BUKAN (inversi logis)

&& DAN (perkalian logis)

|| ATAU (penjumlahan logis)

Tabel 14.6. Hasil eksekusi operator AND dan OR

Operan 1

Operan 2

Tabel 14.7. Hasil eksekusi operator NOT

tipe dapatkan operator

Ketik dapatkan operator typeof mengembalikan string yang menjelaskan tipe data operan. Operan yang ingin Anda ketahui tipenya ditempatkan setelah operator ini dan diapit tanda kurung:

s = typeof("str");

Sebagai hasil dari eksekusi ekspresi ini, variabel s akan berisi string "string" yang menunjukkan tipe string.

Semua nilai yang dapat dikembalikan oleh operator typeof tercantum dalam tabel. 14.8.

Tabel 14.8. Nilai yang dikembalikan oleh operator typeof

Tipe data

Kembalikan string

Rangkaian

numerik

Tabel 14.8 (akhir)

Tipe data

Kembalikan string

Logis

Kompatibilitas dan konversi tipe data

Saatnya untuk mempertimbangkan dua masalah penting lainnya: kompatibilitas tipe data dan konversi dari satu tipe ke tipe lainnya.

Apa yang Anda dapatkan jika Anda menjumlahkan dua angka? Itu benar - nilai numerik lainnya. Bagaimana jika Anda menambahkan angka dan string? Sulit untuk mengatakannya... Di sini JavaScript menghadapi masalah tipe data yang tidak kompatibel dan mencoba membuat tipe ini kompatibel dengan mengonversi salah satu tipe data ke tipe data lainnya. Pertama-tama ia mencoba mengubah string menjadi angka dan, jika berhasil, melakukan penambahan. Jika tidak berhasil, nomor tersebut akan diubah menjadi string dan dua string yang dihasilkan akan digabungkan. Misalnya, skrip Web pada Listing 14.6 akan mengkonversi nilai b menjadi nilai numerik ketika ditambahkan ke a; dengan demikian variabel c akan berisi nilai 23.

Daftar 14.6

var a, b, c, d, e, f; sebuah = 11;

b = "12"; c = a + b;

d = "JavaScript"; e = 2;

Tetapi karena nilai variabel d tidak dapat diubah menjadi angka, maka nilai e akan diubah menjadi string, dan hasilnya - nilai f - akan menjadi sama dengan

Nilai Boolean dikonversi menjadi nilai numerik atau string, bergantung pada kasus spesifik. Nilai true akan diubah menjadi angka 1 atau string "1" dan nilai false akan diubah menjadi 0 atau "0" . Sebaliknya angka 1 akan diubah menjadi true dan angka 0 akan diubah menjadi false . Juga, false akan diubah menjadi

Kami memiliki nilai null dan undefinisi .

Bagian III. Perilaku halaman web. Skrip web

Dapat dilihat bahwa JavaScript kesulitan untuk mengeksekusi dengan benar ekspresi yang ditulis dengan buruk sekalipun. Kadang-kadang ini berhasil, tetapi lebih sering daripada tidak semuanya tidak berjalan sesuai rencana, dan, pada akhirnya, eksekusi skrip Web terganggu karena kesalahan terdeteksi di tempat yang sama sekali berbeda, pada pernyataan yang benar-benar benar. Oleh karena itu, lebih baik hindari kejadian seperti itu.

Prioritas operator

Masalah terakhir yang akan kita bahas di sini adalah prioritas operator. Seperti yang kita ingat, prioritas mempengaruhi urutan eksekusi operator dalam ekspresi.

Biarkan ada ekspresi berikut:

Dalam hal ini, pertama-tama nilai c akan ditambahkan ke nilai variabel b, dan kemudian 10 akan dikurangi dari jumlahnya. Operator ekspresi ini memiliki prioritas yang sama dan oleh karena itu dieksekusi secara ketat dari kiri ke kanan.

Sekarang perhatikan ungkapan ini:

Di sini, nilai c pertama-tama akan dikalikan 10, baru kemudian nilai b akan ditambahkan ke hasil perkaliannya. Operator perkalian memiliki prioritas lebih tinggi dibandingkan operator penjumlahan, sehingga urutan "kiri ke kanan" akan dipatahkan.

Operator penugasan memiliki prioritas terendah. Itu sebabnya ekspresi itu sendiri dievaluasi terlebih dahulu, dan kemudian hasilnya ditugaskan ke variabel.

DI DALAM Secara umum, prinsip dasar untuk mengeksekusi semua operator adalah sebagai berikut: operator dengan prioritas lebih tinggi akan dieksekusi terlebih dahulu, baru kemudian operator dengan prioritas lebih rendah. Operator dengan prioritas yang sama dieksekusi sesuai urutan kemunculannya (dari kiri ke kanan).

DI DALAM meja 14.9 mencantumkan semua operator yang kami pelajari dalam urutan prioritasnya.

Tabel 14.9. Prioritas operator (dalam urutan menurun)

Operator

Keterangan

++ -- - ~ ! jenis

Kenaikan, penurunan, perubahan tanda, BUKAN logis, definisi tipe

Perkalian, pembagian, sisa

Penjumlahan dan penggabungan string, pengurangan

Operator Perbandingan

Logis DAN

Bab 14. Pengantar Pemrograman Web. bahasa JavaScript

Tabel 14.9 (akhir)

Operator

Keterangan

Logis ATAU

Operator bersyarat(lihat di bawah)

= <оператор>=

Tugas, sederhana dan kompleks

PERHATIAN!

Ingat tabel ini. Eksekusi pernyataan yang tidak tepat dapat menyebabkan kesalahan yang sulit dideteksi, dimana ekspresi yang tampaknya benar-benar benar menghasilkan hasil yang salah.

Namun bagaimana jika kita perlu melanggar urutan normal eksekusi pernyataan? Mari kita gunakan tanda kurung. Ketika ditulis dengan cara ini, pernyataan yang diapit tanda kurung akan dieksekusi terlebih dahulu:

a = (b + c) * 10;

Di sini, nilai variabel b dan c akan dijumlahkan terlebih dahulu, lalu jumlah yang dihasilkan akan dikalikan 10.

Operator yang diapit tanda kurung juga harus diutamakan. Inilah sebabnya mengapa beberapa tanda kurung sering digunakan:

a = ((b + c) * 10 - d) / 2 + 9;

Di sini operator akan dieksekusi dalam urutan berikut:

1. Penambahan b dan c.

2. Kalikan jumlah yang dihasilkan dengan 10.

3. Mengurangi d dari hasil kali.

4. Bagilah selisihnya dengan 2.

5. Menambahkan 9 ke hasil bagi.

Jika Anda menghapus tanda kurung:

a = b + c * 10 - d / 2 + 9;

maka urutan pelaksanaan operatornya adalah sebagai berikut:

1. Mengalikan c dan 10.

2. Bagi d dengan 2.

3. Penjumlahan b dan hasil kali c dan 10.

4. Mengurangi hasil bagi dari pembagian dari jumlah yang dihasilkan d oleh 2.

5. Tambahkan 9 ke perbedaan yang dihasilkan.

Ternyata hasilnya sangat berbeda, bukan?

  • Tidak terdefinisi: "tidak terdefinisi"
  • Batal: "objek"
  • Boolean: "boolean"
  • Nomor: "angka"
  • Tali: "tali"
  • Fungsi: "fungsi"
  • Segala sesuatu yang lain: "objek"

Catatan berikut harus ditambahkan ke tabel ini:

1. typeof null === "objek" .

Secara teoritis, ada poin halus di sini. Dalam bahasa yang diketik secara statis, variabel tipe objek tidak boleh berisi objek (NULL, nil, null pointer).

Dalam praktiknya, hal ini merepotkan dalam JavaScript. Jadi pengembang ES 5.1 akan melakukan sesuatu yang lebih intuitif: typeof null === "null" .

Tapi karena kita masih punya ES3, jangan salah, misalnya dengan ini:

/* Fungsi mencari beberapa objek dan mengembalikannya atau null jika tidak ada yang ditemukan */ function search() () var obj = search(); if (typeof obj === "object") ( // apakah kita benar-benar menemukan objek tersebut (FAIL) obj.method(); )

2. Jangan lupa tentang objek pembungkus (tipe Angka baru(5) === “objek”).

3. Dan jangan lupa tentang hak browser untuk melakukan apapun yang mereka inginkan dengan objek host.

Jangan kaget bahwa Safari dengan keras kepala menganggap HTMLCollection sebagai tipe fungsi, dan IE sebelum versi 9 mempertahankan fungsi alert() favorit kami sebagai objek. Selain itu, Chrome dulu menganggap RegExp sebagai sebuah fungsi, tetapi sekarang tampaknya sudah sadar dan meresponsnya dengan object .

keString()

Mencoba mencari tahu tipe suatu nilai dari hasil metode toString() tidak ada gunanya. Di semua “kelas” metode ini ditimpa sendiri.

Metode ini bagus untuk menampilkan informasi debug, tetapi tidak dapat digunakan untuk menentukan tipe suatu variabel.

Objek.prototipe.toString()

Meskipun toString diganti dalam "kelas" tertentu, kami masih memiliki implementasi aslinya dari Object. Mari kita coba menggunakannya:

console.log(Object.prototype.toString.call(nilai));

console.log(Object.prototype.toString.call(nilai));


Clinton meringankan kebosanan ini

Anehnya, metode ini ternyata bekerja dengan sangat baik.

Untuk tipe skalar, mengembalikan , , , .

Lucunya, bahkan New Number(5) yang typeof failed here kembali.

Metode ini gagal pada null dan tidak terdefinisi. Browser yang berbeda kembali, terkadang diharapkan dan terkadang, terkadang secara umum. Namun, Anda dapat dengan mudah menentukan jenis kedua nilai ini tanpa ini.

Hal-hal menjadi menarik ketika kita sampai pada objek (yang memiliki typeof === "object").

objek bawaan bekerja dengan sangat baik:

  • {} —
  • Tanggal -
  • Kesalahan —
  • RegExp —

Satu-satunya hal adalah argumen tersebut tidak termasuk dalam daftar argumen, yaitu .
Segalanya menjadi lebih buruk lagi dengan objek host.

Di IE, objek DOM mulai menjadi objek “normal” hanya dari versi 8, itupun belum sepenuhnya. Oleh karena itu, di IE 6-8, semua objek ini (HTMLCOllection, DOMElement, TextNode, serta dokumen dan jendela) direduksi menjadi .

Di semua browser lain (termasuk IE9), Anda sudah dapat melakukan sesuatu dengan hasil toString. Meskipun semuanya juga tidak mudah: HTMLCollection ada di sana. jendela - lalu, lalu, lalu. Tapi Anda sudah bisa mencoba mendapatkan sesuatu dari ini.

Lebih rumit dengan DOMElement: ditampilkan dalam bentuk, - format berbeda untuk setiap tag. Tapi musim reguler juga akan membantu kami di sini.

Ceritanya kira-kira sama dengan objek host lainnya (dalam tes lokasi dan navigator). Di mana pun kecuali IE, mereka dapat diidentifikasi melalui garis.

Kekurangan menggunakan Object.prototype.toString():

1. Kemungkinan ini tidak tercakup dalam standar. Dan di sini kita seharusnya bergembira karena semuanya berjalan dengan baik, daripada meratapi beberapa kekurangannya.

2. Menentukan suatu tipe dengan mengurai string yang dikembalikan dengan metode yang tidak digunakan untuk menentukan suatu tipe sama sekali, dan juga dipanggil pada objek yang tidak berlaku, meninggalkan sedikit endapan di jiwa.

3. Di IE lama, seperti yang Anda lihat, tidak mengidentifikasi objek host adalah hal yang normal.

Namun, ini adalah hal yang berfungsi sepenuhnya bila digunakan bersama dengan cara lain.


Konstruktor

Dan terakhir, para desainer. Siapa yang lebih baik mengatakan tentang "kelas" suatu objek di JS selain konstruktornya?

null dan tidak terdefinisi tidak memiliki objek pembungkus maupun konstruktor.

Tipe skalar lainnya memiliki pembungkus, jadi Anda juga bisa mendapatkan konstruktor:

(5).konstruktor === Nomor;

(Nomor .NaN ) .constructor === Nomor ;

(benar).konstruktor === Boolean;

5 contoh Nomor;

// Nomor palsu .NaN contoh Nomor ;

// contoh palsu benar dari Boolean ;

// salah "string" instance dari String ;

// PALSU

5 contoh Nomor; // Nomor palsu.Nomor contoh NaN; // contoh palsu benar dari Boolean; // false "string" instance dari String; // PALSU

(instanceof akan bekerja untuk Nomor baru (5) yang telah lama menderita)

Dengan fungsi (yang juga merupakan objek) instanceof akan berfungsi:

console.log ( (fungsi () ( ) ) instanceof Fungsi ) ;

// true console.log ( (fungsi () ( ) ).konstruktor === Fungsi ) ;

// BENAR

console.log((fungsi () ()) instanceof Fungsi); // true console.log((fungsi () ()).konstruktor === Fungsi); // BENAR

Semua objek kelas bawaan juga mudah diidentifikasi oleh konstruktornya: Array, Tanggal, RegExp, Error.

Satu masalah muncul di sini dengan argumentasi, yang konstruktornya adalah Object .

Dan yang kedua adalah dengan Object itu sendiri, atau lebih tepatnya, bagaimana menetapkan objek yang dibuat melalui konstruktor khusus ke dalamnya.

Dengan cara ini Anda hanya dapat mendefinisikan objek dasar: objek instanceof Objek; Salah satu opsi definisi adalah menelusuri semua kemungkinan tipe lainnya (Array, Error...) dan jika tidak ada yang cocok - "objek".

Konstruktor dan objek host

Segalanya menjadi lebih buruk dengan objek host.

Mari kita mulai dengan fakta bahwa IE hingga dan termasuk versi 7 tidak menganggapnya sebagai objek normal sama sekali. Mereka tidak memiliki desainer dan prototipe di sana (setidaknya seorang programmer tidak dapat menjangkau mereka).

Segalanya lebih baik di browser lain. Ada konstruktor dan Anda dapat menggunakannya untuk menentukan kelas suatu nilai. Mereka hanya dipanggil

browser yang berbeda

berbeda. Misalnya, untuk HTMLCollection, konstruktornya adalah HTMLCollection atau NodeList, atau bahkan NodeListConstructor.
Anda juga harus menentukan konstruktor dasar untuk DOMElement. Di FF, misalnya, HTMLElement , yang sudah diwarisi oleh HTMLDivElement dan lainnya.
Triknya dilemparkan ke FireFox di bawah versi 10 dan Opera di bawah 11. Konstruktor koleksinya ada Object .
konstruktor.nama

Konstruktor juga memiliki properti name, yang dapat berguna.

Tak satu pun dari metode yang disajikan memberikan penentuan 100% jenis/kelas suatu nilai di semua browser. Namun, jika digabungkan, mereka memungkinkan hal ini dilakukan.

Dalam waktu dekat saya akan mencoba mengumpulkan semua data ke dalam tabel dan memberikan contoh fungsi definisi.