Bagaimana untuk menentukan jenis pembolehubah dalam kemahiran javascript_javascript

WBOY
Lepaskan: 2016-05-16 15:46:07
asal
1029 orang telah melayarinya

Dalam JavaScript, terdapat 5 jenis data asas dan 1 jenis data kompleks Jenis data asas ialah: Undefined, Null, Boolean, Number dan String jenis data kompleks ialah Object, dan Object juga dibahagikan kepada banyak jenis tertentu . Jenis, seperti: Tatasusunan, Fungsi, Tarikh, dsb. Hari ini kita akan membincangkan cara menentukan jenis pembolehubah.

Sebelum menerangkan pelbagai kaedah, kami terlebih dahulu mentakrifkan beberapa pembolehubah ujian untuk melihat cara kaedah seterusnya boleh menghuraikan jenis pembolehubah berikut hampir termasuk jenis yang biasa kami gunakan dalam pengekodan sebenar.

var num = 123;
var str = 'abcdef';
var bool = true;
var arr = [1, 2, 3, 4];
var json = {name:'wenzi', age:25};
var func = function(){ console.log('this is function'); }
var und = undefined;
var nul = null;
var date = new Date();
var reg = /^[a-zA-Z]{5,20}$/;
var error= new Error();
Salin selepas log masuk

1. Gunakan jenis pengesanan

Apa yang selalu kami gunakan ialah menggunakan typeof untuk mengesan jenis pembolehubah. Kali ini, kami juga menggunakan typeof untuk mengesan jenis pembolehubah:

console.log(
	typeof num, 
	typeof str, 
	typeof bool, 
	typeof arr, 
	typeof json, 
	typeof func, 
	typeof und, 
	typeof nul, 
	typeof date, 
	typeof reg, 
	typeof error
);
// number string boolean object	object function undefined object object object object
Salin selepas log masuk

Berdasarkan hasil keluaran, arr, json, nul, date, reg, error semuanya dikesan sebagai jenis objek dan pembolehubah lain boleh dikesan dengan betul. Apabila anda perlu menentukan sama ada pembolehubah adalah daripada jenis nombor, rentetan, boolean, fungsi, tidak ditentukan atau json, anda boleh menggunakan typeof untuk menentukan. Jenis pembolehubah lain tidak boleh ditentukan, termasuk null.
Juga, typeof tidak dapat membezakan antara jenis tatasusunan dan json. Kerana apabila menggunakan pembolehubah jenis, kedua-dua tatasusunan dan json jenis objek output.

2. Gunakan pengesanan contoh

Dalam JavaScript, operator jenis sering digunakan untuk menentukan jenis pembolehubah Apabila menggunakan operator jenis, masalah timbul apabila menggunakan jenis rujukan untuk menyimpan nilai Tidak kira jenis objek yang dirujuk, ia mengembalikan "objek " ". ECMAScript memperkenalkan satu lagi contoh operator Java untuk menyelesaikan masalah ini. Operator instanceof adalah serupa dengan operator typeof dan digunakan untuk mengenal pasti jenis objek yang sedang diproses. Tidak seperti kaedah typeof, kaedah instanceof memerlukan pembangun untuk mengesahkan secara eksplisit bahawa objek adalah jenis tertentu. Contohnya:

function Person(){

}
var Tom = new Person();
console.log(Tom instanceof Person); // true
Salin selepas log masuk


Mari lihat contoh berikut sekali lagi:

function Person(){

}
function Student(){

}
Student.prototype = new Person();
var John = new Student();
console.log(John instanceof Student); // true
console.log(John instancdof Person); // true
Salin selepas log masuk


instanceof juga boleh mengesan perhubungan warisan berbilang peringkat.
Okey, mari gunakan instanceof untuk mengesan pembolehubah di atas:

console.log(
	num instanceof Number,
	str instanceof String,
	bool instanceof Boolean,
	arr instanceof Array,
	json instanceof Object,
	func instanceof Function,
	und instanceof Object,
	nul instanceof Object,
	date instanceof Date,
	reg instanceof RegExp,
	error instanceof Error
)
// num : false 
// str : false 
// bool : false 
// arr : true 
// json : true 
// func : true 
// und : false 
// nul : false 
// date : true 
// reg : true 
// error : true
Salin selepas log masuk

Daripada hasil yang dijalankan di atas, kita dapat melihat bahawa jenis num, str dan bool belum dikesan, tetapi apabila kita mencipta num menggunakan kaedah berikut, jenis itu boleh dikesan:

var num = new Number(123);
var str = new String('abcdef');
var boolean = new Boolean(true);
Salin selepas log masuk

Pada masa yang sama, kita juga perlu melihat bahawa und dan nul dikesan jenis Objek, jadi ia menghasilkan benar, kerana tiada jenis global Undefined dan Null dalam js Kedua-dua und dan nul tergolong dalam jenis Objek, jadi mereka adalah output benar.

3. Gunakan pembina untuk mengesan

Apabila menggunakan instanceof untuk mengesan jenis pembolehubah, kami tidak dapat mengesan jenis nombor, 'rentetan' dan bool. Oleh itu, kita perlu mencari jalan lain untuk menyelesaikan masalah ini.
pembina pada asalnya adalah harta pada objek prototaip, menunjuk kepada pembina. Walau bagaimanapun, mengikut susunan objek contoh mencari atribut, jika tiada atribut contoh atau kaedah pada objek contoh, ia akan dicari pada rantaian prototaip Oleh itu, objek contoh juga boleh menggunakan atribut pembina.
Mari kita keluarkan kandungan num.constructor, iaitu, rupa bentuk pembolehubah jenis angka:

fungsi Nombor() { [kod asli] }

Kita dapat melihat bahawa ia menunjuk kepada pembina Nombor Oleh itu, kita boleh menggunakan num.constructor==Number untuk menentukan sama ada num adalah jenis Number

function Person(){

}
var Tom = new Person();

// undefined和null没有constructor属性
console.log(
	Tom.constructor==Person,
	num.constructor==Number,
	str.constructor==String,
	bool.constructor==Boolean,
	arr.constructor==Array,
	json.constructor==Object,
	func.constructor==Function,
	date.constructor==Date,
	reg.constructor==RegExp,
	error.constructor==Error
);
// 所有结果均为true
Salin selepas log masuk
Daripada hasil keluaran, kita dapat melihat bahawa kecuali undefined dan null, jenis jenis pembolehubah lain boleh ditentukan menggunakan pembina.

Walau bagaimanapun, menggunakan pembina adalah tidak selamat, kerana atribut pembina boleh diubah suai, yang akan menyebabkan keputusan yang dikesan menjadi salah, contohnya:

function Person(){

}
function Student(){

}
Student.prototype = new Person();
var John = new Student();
console.log(John.constructor==Student); // false
console.log(John.constructor==Person); // true
Salin selepas log masuk
Dalam contoh di atas, pembina dalam prototaip Pelajar diubah suai untuk menunjuk kepada Orang, menyebabkan fakta bahawa pembina sebenar objek contoh John tidak dapat dikesan.

Pada masa yang sama, apabila menggunakan instanceof dan constructor, tatasusunan yang dinilai mesti diisytiharkan pada halaman semasa! Sebagai contoh, halaman (halaman induk) mempunyai bingkai, dan halaman (halaman anak) dirujuk dalam bingkai Tatasusunan diisytiharkan dalam halaman anak dan diberikan kepada pembolehubah halaman induk dinilai, Array == object.constructor; 1. Array ialah data rujukan Semasa proses pemindahan, ia hanyalah pemindahan alamat rujukan.
2. Alamat yang dirujuk oleh objek asli Array setiap halaman adalah berbeza Pembina tatasusunan yang sepadan yang diisytiharkan pada sub-halaman ialah objek Array bagi halaman induk membuat pertimbangan, dan Array yang digunakan ialah tidak sama dengan Array subhalaman; jika tidak, ia akan menjadi sukar untuk mengesan masalah!

4. Gunakan Object.prototype.toString.call
Mari kita tidak peduli tentang perkara ini, mari kita lihat dahulu cara ia mengesan jenis pembolehubah:

从输出的结果来看,Object.prototype.toString.call(变量)输出的是一个字符串,字符串里有一个数组,第一个参数是Object,第二个参数就是这个变量的类型,而且,所有变量的类型都检测出来了,我们只需要取出第二个参数即可。或者可以使用Object.prototype.toString.call(arr)=="object Array"来检测变量arr是不是数组。
我们现在再来看看ECMA里是是怎么定义Object.prototype.toString.call的:

复制代码 代码如下:

Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)

上面的规范定义了Object.prototype.toString的行为:首先,取得对象的一个内部属性[[Class]],然后依据这个属性,返回一个类似于”[object Array]”的字符串作为结果(看过ECMA标准的应该都知道,[[]]用来表示语言内部用到的、外部不可直接访问的属性,称为“内部属性”)。利用这个方法,再配合call,我们可以取得任何对象的内部属性[[Class]],然后把类型检测转化为字符串比较,以达到我们的目的。
5. jquery中$.type的实现

在jquery中提供了一个$.type的接口,来让我们检测变量的类型:

console.log(
	$.type(num),
	$.type(str),
	$.type(bool),
	$.type(arr),
	$.type(json),
	$.type(func),
	$.type(und),
	$.type(nul),
	$.type(date),
	$.type(reg),
	$.type(error)
);
// number string boolean array object function undefined null date regexp error
Salin selepas log masuk

Adakah ia berasa biasa apabila anda melihat output? Ya, ia adalah parameter kedua output hasil menggunakan Object.prototype.toString.call (pembolehubah) di atas.
Mula-mula mari kita bandingkan hasil pengesanan semua kaedah di atas Baris mendatar ialah kaedah pengesanan yang digunakan dan baris menegak ialah setiap pembolehubah:

类型判断 jenis contoh pembina kepadaString.panggilan $.type
bilangan nombor palsu benar [Nombor objek] nombor
str rentetan palsu benar [Rentetan objek] rentetan
bool boolean palsu benar [objek Boolean] boolean
arr objek benar benar [Susun Objek] tatasusunan
json objek benar benar [Objek objek] objek
berfungsi fungsi benar benar [Fungsi objek] fungsi
dan tidak ditentukan palsu - [objek Tidak Ditakrifkan] tidak ditentukan
nul objek palsu - [objek Null] null
tarikh objek benar benar [Tarikh objek] tarikh
reg objek benar benar [objek RegExp] regexp
ralat objek benar benar [Ralat objek] ralat
Kelebihan Mudah digunakan dan boleh mengeluarkan hasil secara langsung Boleh mengesan jenis kompleks Pada asasnya dapat mengesan semua jenis Kesan semua jenis -
Keburukan Terlalu sedikit jenis dikesan Jenis asas tidak dapat dikesan dan tidak boleh merentas iframe Tidak boleh menyeberangi iframe, dan pembina mudah diubah suai Di bawah IE6, undefined dan null adalah kedua-duanya Objek -

这样对比一下,就更能看到各个方法之间的区别了,而且Object.prototype.toString.call和$type输出的结果真的很像。我们来看看jquery(2.1.2版本)内部是怎么实现$.type方法的:

// 实例对象是能直接使用原型链上的方法的
var class2type = {};
var toString = class2type.toString;

// 省略部分代码...

type: function( obj ) {
	if ( obj == null ) {
		return obj + "";
	}
	// Support: Android<4.0, iOS<6 (functionish RegExp)
	return (typeof obj === "object" || typeof obj === "function") &#63;
		(class2type[ toString.call(obj) ] || "object") :
		typeof obj;
},

// 省略部分代码... 

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
Salin selepas log masuk

我们先来看看jQuery.each的这部分:

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
	class2type[ "[object " + name + "]" ] = name.toLowerCase();
});

//循环之后,`class2type`的值是: 
class2type = {
	'[object Boolean]' : 'boolean', 
	'[object Number]' : 'number',
	'[object String]' : 'string',
	'[object Function]': 'function',
	'[object Array]'  : 'array',
	'[object Date]'  : 'date',
	'[object RegExp]' : 'regExp',
	'[object Object]' : 'object',
	'[object Error]'  : 'error'
}
Salin selepas log masuk

再来看看type方法:

// type的实现
type: function( obj ) {
	// 若传入的是null或undefined,则直接返回这个对象的字符串
	// 即若传入的对象obj是undefined,则返回"undefined"
	if ( obj == null ) {
		return obj + "";
	}
	// Support: Android<4.0, iOS<6 (functionish RegExp)
	// 低版本regExp返回function类型;高版本已修正,返回object类型
	// 若使用typeof检测出的obj类型是object或function,则返回class2type的值,否则返回typeof检测的类型
	return (typeof obj === "object" || typeof obj === "function") &#63;
		(class2type[ toString.call(obj) ] || "object") :
		typeof obj;
}
Salin selepas log masuk

当typeof obj === "object" || typeof obj === "function"时,就返回class2type[ toString.call(obj)。到这儿,我们就应该明白为什么Object.prototype.toString.call和$.type那么像了吧,其实jquery中就是用Object.prototype.toString.call实现的,把'[object Boolean]'类型转成'boolean'类型并返回。若class2type存储的没有这个变量的类型,那就返回”object”。
除了”object”和”function”类型,其他的类型则使用typeof进行检测。即number, string, boolean类型的变量,使用typeof即可。

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan