Heim > Web-Frontend > js-Tutorial > Hauptteil

So bestimmen Sie den Variablentyp in Javascript_Javascript-Kenntnissen

WBOY
Freigeben: 2016-05-16 15:46:07
Original
1033 Leute haben es durchsucht

In JavaScript gibt es 5 grundlegende Datentypen und 1 komplexen Datentyp: Undefiniert, Null, Boolean, Zahl und String; der komplexe Datentyp ist ebenfalls in viele spezifische Typen unterteilt . Typ, wie zum Beispiel: Array, Funktion, Datum usw. Heute besprechen wir, wie man den Typ einer Variablen bestimmt.

Bevor wir die verschiedenen Methoden erläutern, definieren wir zunächst einige Testvariablen, um zu sehen, wie die folgenden Variablentypen fast die Typen analysieren können, die wir üblicherweise in der tatsächlichen Codierung verwenden.

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();
Nach dem Login kopieren

1. Art der Erkennung verwenden

Was wir normalerweise am häufigsten verwenden, ist die Verwendung von typeof zum Erkennen von Variablentypen. Dieses Mal verwenden wir auch typeof, um den Typ der Variablen zu ermitteln:

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
Nach dem Login kopieren

Den Ausgabeergebnissen nach zu urteilen, werden arr, json, nul, date, reg, error alle als Objekttypen erkannt, und andere Variablen können korrekt erkannt werden. Wenn Sie feststellen müssen, ob eine Variable vom Typ Zahl, Zeichenfolge, Boolescher Wert, Funktion, Undefiniert oder JSON ist, können Sie zur Bestimmung typeof verwenden. Der Typ anderer Variablen, einschließlich Null, kann nicht bestimmt werden.
Außerdem kann typeof nicht zwischen Array- und JSON-Typen unterscheiden. Denn bei Verwendung der Variable typeof geben sowohl Array- als auch JSON-Typen Objekte aus.

2. Instanzerkennung verwenden

In JavaScript wird der Typeof-Operator häufig verwendet, um den Typ einer Variablen zu bestimmen. Bei der Verwendung des Typeof-Operators tritt ein Problem auf, wenn Referenztypen zum Speichern von Werten verwendet werden. Unabhängig davon, auf welchen Objekttyp verwiesen wird, gibt er „Objekt“ zurück ". ECMAScript führt eine weitere Java-Operatorinstanz ein, um dieses Problem zu lösen. Der Instanz-Operator ähnelt dem Typ-Operator und wird verwendet, um den Typ des verarbeiteten Objekts zu identifizieren. Im Gegensatz zur Methode „typeof“ muss der Entwickler bei der Methode „instanceof“ explizit bestätigen, dass das Objekt von einem bestimmten Typ ist. Zum Beispiel:

function Person(){

}
var Tom = new Person();
console.log(Tom instanceof Person); // true
Nach dem Login kopieren


Schauen wir uns noch einmal das folgende Beispiel an:

function Person(){

}
function Student(){

}
Student.prototype = new Person();
var John = new Student();
console.log(John instanceof Student); // true
console.log(John instancdof Person); // true
Nach dem Login kopieren


Instanceof kann auch mehrstufige Vererbungsbeziehungen erkennen.
Okay, verwenden wir „instanceof“, um die oben genannten Variablen zu erkennen:

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
Nach dem Login kopieren

Aus den obigen Laufergebnissen können wir ersehen, dass der Typ von num, str und bool nicht erkannt wurde, aber wenn wir num mit der folgenden Methode erstellen, kann der Typ erkannt werden:

var num = new Number(123);
var str = new String('abcdef');
var boolean = new Boolean(true);
Nach dem Login kopieren

Gleichzeitig müssen wir auch sehen, dass und und nul erkannte Objekttypen sind, sodass sie true ausgeben, da es in js keine globalen Typen von Undefiniert und Null gibt. Sowohl und als auch nul gehören zum Objekttyp. Sie sind also wahr.

3. Verwenden Sie den Konstruktor, um

zu erkennen

Wenn wir „instanceof“ zum Erkennen von Variablentypen verwenden, können wir die Typen „Zahl“, „Zeichenfolge“ und „Bool“ nicht erkennen. Deshalb müssen wir einen anderen Weg finden, dieses Problem zu lösen.
Konstruktor ist ursprünglich eine Eigenschaft des Prototypobjekts, die auf den Konstruktor verweist. Wenn jedoch kein Instanzattribut oder keine Instanzmethode für das Instanzobjekt vorhanden ist, wird entsprechend der Reihenfolge, in der das Instanzobjekt nach Attributen sucht, in der Prototypenkette gesucht. Daher kann das Instanzobjekt auch das Konstruktorattribut verwenden.
Lassen Sie uns zunächst den Inhalt von num.constructor ausgeben, also wie der Konstruktor einer Variablen vom numerischen Typ aussieht:

Funktionsnummer() { [nativer Code] }

Wir können sehen, dass es auf den Konstruktor von Number zeigt. Daher können wir num.constructor==Number verwenden, um zu bestimmen, ob num vom Typ Number ist:

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
Nach dem Login kopieren

Aus den Ausgabeergebnissen können wir ersehen, dass außer undefiniert und null der Typ anderer Variablentypen mithilfe des Konstruktors bestimmt werden kann.
Die Verwendung des Konstruktors ist jedoch nicht sicher, da das Konstruktorattribut geändert werden kann, was dazu führen kann, dass die erkannten Ergebnisse falsch sind, zum Beispiel:

function Person(){

}
function Student(){

}
Student.prototype = new Person();
var John = new Student();
console.log(John.constructor==Student); // false
console.log(John.constructor==Person); // true
Nach dem Login kopieren

Im obigen Beispiel wird der Konstruktor im Student-Prototyp so geändert, dass er auf Person zeigt, was dazu führt, dass der tatsächliche Konstruktor des Instanzobjekts John nicht erkannt werden kann.
Gleichzeitig muss bei Verwendung von Instanz von und Konstruktor das zu beurteilende Array auf der aktuellen Seite deklariert werden! Beispielsweise verfügt eine Seite (übergeordnete Seite) über einen Frame, und in diesem Frame wird auf eine Seite (untergeordnete Seite) verwiesen, die einer Variablen der übergeordneten Seite zugewiesen wird wird beurteilt, Array == object.constructor; gibt false zurück; Grund:
1. Das Array besteht aus Referenzdaten. Während des Übertragungsvorgangs erfolgt nur die Übertragung der Referenzadresse.
2. Die Adresse, auf die das native Array-Objekt jeder Seite verweist, ist unterschiedlich. Der entsprechende Konstruktor des auf der Unterseite deklarierten Arrays ist das Array-Objekt der übergeordneten Seite, und das verwendete Array ist nicht gleich Array von Unterseiten; denken Sie daran, sonst wird es schwierig, das Problem aufzuspüren!
4. Verwenden Sie Object.prototype.toString.call

Kümmern wir uns nicht darum, was das ist, werfen wir zunächst einen Blick darauf, wie es Variablentypen erkennt:

console.log(
	Object.prototype.toString.call(num),
	Object.prototype.toString.call(str),
	Object.prototype.toString.call(bool),
	Object.prototype.toString.call(arr),
	Object.prototype.toString.call(json),
	Object.prototype.toString.call(func),
	Object.prototype.toString.call(und),
	Object.prototype.toString.call(nul),
	Object.prototype.toString.call(date),
	Object.prototype.toString.call(reg),
	Object.prototype.toString.call(error)
);
// '[object Number]' '[object String]' '[object Boolean]' '[object Array]' '[object Object]'
// '[object Function]' '[object Undefined]' '[object Null]' '[object Date]' '[object RegExp]' '[object Error]'
Nach dem Login kopieren

从输出的结果来看,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
Nach dem Login kopieren

Kommt es Ihnen bekannt vor, wenn Sie die Ausgabe sehen? Ja, es ist der zweite Parameter der Ergebnisausgabe mit Object.prototype.toString.call (Variable) oben.
Vergleichen wir zunächst die Erkennungsergebnisse aller oben genannten Methoden. Die horizontale Reihe ist die verwendete Erkennungsmethode und die vertikale Reihe ist jede Variable:

类型判断 Typ instanceof Konstrukteur toString.call $.type
Anzahl Nummer falsch wahr [Objektnummer] Nummer
str Zeichenfolge falsch wahr [Objektzeichenfolge] Zeichenfolge
bool boolean falsch wahr [Objekt Boolean] boolean
arr Objekt wahr wahr [Objektarray] Array
json Objekt wahr wahr [Objekt Objekt] Objekt
Funktion Funktion wahr wahr [Objektfunktion] Funktion
und undefiniert falsch - [Objekt undefiniert] undefiniert
nul Objekt falsch - [Objekt Null] null
Datum Objekt wahr wahr [Objektdatum] Datum
reg Objekt wahr wahr [object RegExp] regexp
Fehler Objekt wahr wahr [Objektfehler] Fehler
Vorteile Einfach zu bedienen und kann Ergebnisse direkt ausgeben Kann komplexe Typen erkennen Grundsätzlich in der Lage, alle Typen zu erkennen Alle Typen erkennen -
Nachteile Zu wenige Typen erkannt Basistypen können nicht erkannt werden und können keine Iframes überschreiten Iframes können nicht überquert werden und der Konstruktor kann leicht geändert werden Unter IE6 sind undefiniert und null beide Objekte -

这样对比一下,就更能看到各个方法之间的区别了,而且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();
});
Nach dem Login kopieren

我们先来看看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'
}
Nach dem Login kopieren

再来看看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;
}
Nach dem Login kopieren

当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即可。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage