Dalam JavaScript, cara yang paling boleh dipercayai untuk menentukan jenis terbina dalam nilai objek adalah melalui kaedah Object.prototype.toString.
var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]"
Apa yang akan dibincangkan oleh artikel ini ialah cara kaedah toString melakukan ini dan apakah prinsipnya.
ECMAScript 3
Dalam ES3, spesifikasi kaedah Object.prototype.toString adalah seperti berikut:
15.2.4.2 Object.prototype.toString()
Apabila kaedah toString dipanggil, langkah berikut akan dilakukan:
1. Dapatkan nilai atribut [[Kelas]] objek ini.
2. Kira tiga rentetan "[objek", hasil operasi Hasil(1) langkah pertama dan rentetan baharu selepas gabungan "]".
3. Kembalikan hasil operasi langkah kedua Keputusan(2).
[[Kelas]] ialah sifat dalaman yang dimiliki oleh semua objek (objek asli dan objek hos) Dalam spesifikasi, [[Kelas]] ditakrifkan seperti ini
内部属性 | 描述 |
---|---|
[[Class]] | 一个字符串值,表明了该对象的类型. |
Kemudian dia memberi penjelasan:
Nilai atribut [[Class]] bagi semua objek terbina dalam ditakrifkan oleh spesifikasi ini Nilai atribut [[Class]] bagi semua objek hos boleh menjadi sebarang nilai, malah [[Class]. digunakan oleh atribut objek terbina dalam ] Nilai atribut [[Class]] boleh digunakan untuk menentukan jenis terbina dalam milik objek asli. Perlu diingatkan bahawa spesifikasi ini tidak menyediakan sebarang cara lain kecuali melalui kaedah Object.prototype.toString. Biarkan program mengakses nilai harta (lihat 15.2.4.2).
Dalam erti kata lain, rentetan yang dikembalikan oleh kaedah Object.prototype.toString, alih keluar "[objek" tetap di hadapan dan "]" tetap di belakang, ialah nilai atribut dalaman [[class] ], yang dicapai Tujuan menentukan jenis objek Kaedah alat $.type() dalam jQuery digunakan untuk ini
Dalam ES3, dokumen spesifikasi tidak meringkaskan berapa banyak jenis sifat dalaman [[kelas]] yang ada, tetapi kita boleh mengira sendiri Terdapat sejumlah 10 nilai [[kelas]. ] sifat dalaman objek asli masing-masing ialah: "Array", "Boolean", "Date", "Error", "Function", "Math", "Nombor", "Objek", "RegExp", "String" .
ECMAScript 5
Dalam ES5.1, selain spesifikasi ditulis dengan lebih terperinci, terdapat juga beberapa perubahan dalam takrifan kaedah Object.prototype.toString dan sifat dalaman [[class]]. kaedah prototype.toString adalah seperti berikut:
15.2.4.2 Object.prototype.toString ( )
Apabila kaedah toString dipanggil, langkah berikut akan dilakukan:Jika nilai ini tidak ditentukan, kembalikan "[objek Tidak Ditakrifkan]".
Nilai atribut [[Class]] bagi semua objek terbina dalam ditakrifkan oleh spesifikasi ini Nilai atribut [[Class]] bagi semua objek hos boleh kecuali "Arguments", "Array", "Boolean", "Tarikh ", "Ralat", "Fungsi", "JSON", "Math", "Nombor", "Objek", "RegExp", "String" ialah enjin yang digunakan secara Dalaman untuk menentukan jenis nilai yang dimiliki objek. Perlu diingat bahawa spesifikasi ini tidak menyediakan cara lain untuk program mengakses nilai harta ini kecuali melalui kaedah Object.prototype.toString (lihat 15.2.4.2).
Berbanding dengan ES3, perbezaan pertama ialah [[class]] mempunyai dua lagi nilai atribut dalaman, menjadi 12 jenis Satu ialah [[class]] objek argumen menjadi "Argumen", dan Daripada yang sebelumnya "Objek", terdapat berbilang objek global JSON, yang nilai [[kelas]]nya ialah "JSON". Perbezaan kedua ialah nilai harta dalaman [[kelas]] objek hos tidak boleh Ia bercanggah dengan 12 ini nilai, tetapi dalam penyemak imbas yang menyokong ES3, nampaknya tiada objek hos yang sengaja menggunakan 10 nilai tersebut
ECMAScript 6 ES6 masih hanya draf yang berfungsi, tetapi yang pasti atribut dalaman [[class]] hilang dan digantikan dengan atribut dalaman yang lain [[NativeBrand]]. :
内部属性 | 属性值 | 描述 |
---|---|---|
[[NativeBrand]] | 枚举NativeBrand的一个成员. | 该属性的值对应一个标志值(tag value),可以用来区分原生对象的类型. |
[[NativeBrand]] penjelasan atribut:
[[NativeBrand]] sifat dalaman digunakan untuk mengenal pasti sama ada objek asli ialah jenis objek tertentu yang mematuhi spesifikasi ini Nilai sifat dalaman [[NativeBrand]] ialah salah satu nilai jenis penghitungan berikut A: NativeFunction, NativeArray, StringWrapper, BooleanWrapper, NumberWrapper, NativeMath, NativeDate, NativeRegExp, NativeError, NativeJSON, NativeArguments, NativePrivateName hanya jenis dalaman ScriptMAish yang khusus digunakan untuk membezakan Jadual 10 Hanya jenis objek yang dinyatakan secara eksplisit mempunyai sifat dalaman [[NativeBrand]].
Jadual 10 — Nilai sifat dalaman [[NativeBrand]]
属性值 | 对应类型 |
---|---|
NativeFunction | Objek fungsi |
NativeArray | Objek tatasusunan |
Pembungkus Rentetan | Rentetan objek |
BooleanWrapper | Objek Boolean |
NumberWrapper | Nombor objek |
NativeMath | Objek Matematik |
Tarikh Asli | Objek tarikh |
NativeRegExp | objek RegExp |
NativeError | Ralat objek |
NativeJSON | Objek JSON |
Argumen Asli | Objek hujah |
NativePrivateName | Objek Nama Peribadi |
Ia boleh dilihat bahawa, tidak seperti [[kelas]], tidak setiap objek mempunyai [[NativeBrand]]. Pada masa yang sama, spesifikasi kaedah Object.prototype.toString juga telah ditukar kepada yang berikut:
15.2.4.2 Object.prototype.toString ( )
Apabila kaedah toString dipanggil, langkah berikut akan dilakukan:
Jika nilai ini tidak ditentukan, kembalikan "[objek Tidak Ditakrifkan]".
Jika nilai ini adalah nol, kembalikan "[objek Null]".
Biar O menjadi hasil daripada memanggil ToObject(this).
Jika O mempunyai atribut dalaman [[NativeBrand]], biarkan teg menjadi nilai yang sepadan dalam Jadual 29.
Jika tidak
Biar hasTag menjadi hasil daripada memanggil kaedah dalaman [[HasProperty]] O, dengan parameter @@toStringTag.
Jika hasTag palsu, biarkan teg itu "Objek".
Jika tidak,
Biar teg sebagai hasil daripada memanggil kaedah dalaman [[Get]] O dan parameternya ialah @@toStringTag.
Jika teg adalah penyiapan mendadak, biarkan teg menjadi NormalCompletion("???").
Biar teg menjadi teg.[[nilai]].
Jika Jenis(teg) bukan rentetan, biarkan teg menjadi "???".
Jika nilai teg ialah "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Nombor", "Object", " RegExp ", atau
atau "String", kemudian biarkan teg menjadi hasil penggabungan rentetan "~" dan nilai semasa teg.
Mengembalikan rentetan baharu selepas menggabungkan tiga rentetan "[objek ", teg dan "]".
Jadual 29 — [[NativeBrand]] Nilai Bendera
Valeur [[NativeBrand]] | Valeur du drapeau |
---|---|
FonctionNative | <font face="NSimsun">"Function"</font> |
NativeArray | <font face="NSimsun">"Array"</font> |
StringWrapper | <font face="NSimsun">"String"</font> |
BooleanWrapper | <font face="NSimsun">"Boolean"</font> |
NumberWrapper | <font face="NSimsun">"Number"</font> |
NativeMath | <font face="NSimsun">"Math"</font> |
Tarikh Asli | <font face="NSimsun">"Date"</font> |
NativeRegExp | <font face="NSimsun">"RegExp"</font> |
NativeError | <font face="NSimsun">"Error"</font> |
NativeJSON | <font face="NSimsun">"JSON"</font> |
NativeArguments | <font face="NSimsun">"Arguments"</font> |
可以看到,在规范上有了很大的变化,不过对于普通用户来说,貌似感觉不到.
也许你发现了,ES6里的新类型Map,Set等,都没有在表29中.它们在执行toString方法的时候返回的是什么?
console.log(Object.prototype.toString.call(Map())) //"[object Map]" console.log(Object.prototype.toString.call(Set())) //"[object Set]"
其中的字符串"Map"是怎么来的呢:
15.14.5.13 Map.prototype.@@toStringTag
@@toStringTag 属性的初始值为字符串"Map".
由于ES6的规范还在制定中,各种相关规定都有可能改变,所以如果想了解更多细节.看看下面这两个链接,现在只需要知道的是:[[class]]没了,使用了更复杂的机制.
以上所述是小编给大家分享的JavaScript中Object.prototype.toString方法的原理,希望对大家有所帮助!