Es gibt mehrere Möglichkeiten, den Datentyp zu bestimmen
1. Unärer Operator typeOf
2. Vergleichsoperatorinstanz von
3. Konstruktorattribut
4. Prototypattribut
1. Art von
Die Rückgabewerte von typeof sind wie folgt
Typ | Struktur |
---|---|
Undefiniert | "undefined" |
Null |
"object" (siehe unten) |
Boolescher Wert | "boolean" |
Wert | "number" |
Zeichenfolge | "string" |
Symbol (neu in ECMAScript 6) | "symbol" |
Hostobjekt (bereitgestellt von der JS-Umgebung, z. B. Browser) | Implementierungsabhängig |
Funktionsobjekt (implementiert [[Call]] in ECMA-262-Begriffen) | "function" |
Jedes andere Objekt | "object" |
Einfache und grobe Methode, schauen Sie sich einfach den Code an
// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 // Numbers console.log(typeof 37 === 'number'); console.log(typeof 3.14 === 'number'); console.log(typeof Math.LN2 === 'number'); console.log(typeof Infinity === 'number'); console.log(typeof NaN === 'number'); // 尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" console.log(typeof Number(1) === 'number'); // 不要这样使用! // Strings console.log(typeof "" === 'string'); console.log(typeof "bla" === 'string'); console.log(typeof (typeof 1) === 'string'); // console.log(typeof返回的肯定是一个字符串 console.log(typeof String("abc") === 'string'); // 不要这样使用! // Booleans console.log(typeof true === 'boolean'); console.log(typeof false === 'boolean'); console.log(typeof Boolean(true) === 'boolean'); // 不要这样使用! // Symbols console.log(typeof Symbol() === 'symbol'); console.log(typeof Symbol('foo') === 'symbol'); console.log(typeof Symbol.iterator === 'symbol'); // Undefined console.log(typeof undefined === 'undefined'); console.log(typeof blabla === 'undefined'); // 一个未定义的变量,或者一个定义了却未赋初值的变量 // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 console.log(typeof {a:1} === 'object'); console.log(typeof [1, 2, 4] === 'object'); console.log(typeof /^[a-zA-Z]{5,20}$/ === 'object'); console.log(typeof {name:'wenzi', age:25} === 'object'); console.log(typeof null === 'object');//true // 下面的容易令人迷惑,不要这样使用! console.log(typeof new Boolean(true) === 'object'); console.log(typeof new Number(1) === 'object'); console.log(typeof new Date() === 'object'); console.log(typeof new String("abc") === 'object'); console.log(typeof new Error() === 'object'); // 函数 console.log(typeof function(){} === 'function'); console.log(typeof Math.sin === 'function');
typeof kann nur die oben genannten 7 Typen überprüfen
2. Instanz von
Der Instanzoperator wird verwendet, um den Typ des verarbeiteten Objekts zu identifizieren, sodass Entwickler explizit bestätigen müssen, dass es sich bei dem Objekt um einen bestimmten Typ handelt
1. Instanz von hat nichts mit dem Konstruktor zu tun
var A = function() {}; A.prototype = {}; var B = {}; console.log(A.constructor);//function Function() { [native code] } console.log(B.constructor);//function Object() { [native code] } var a = new A(); A.prototype = {}; var b = new A(); b.constructor = A.constructor; console.log(a.constructor === A);//false console.log(a.constructor);//function Object() { [native code] } console.log(typeof A);//function Object() { [native code] } console.log(a.constructor === b.constructor);//false console.log(b.constructor);//function Function() { [native code] } console.log(a instanceof A);//false console.log(b instanceof A);//true
2. Instanceof wird auch als relationaler Operator bezeichnet, mit dem ermittelt werden kann, ob das Prototypattribut eines bestimmten Konstruktors in der Prototypenkette eines anderen zu erkennenden Objekts vorhanden ist
var str = new String("hello world"); console.log(str instanceof String);//true console.log(String instanceof Function);//true console.log(str instanceof Function);//false
Warum gibt die dritte Ausgabe „false“ zurück? Ursprüngliche Adresse: Eine Frage zur Instanz von in Javascript
//表达式一的指向 console.log(str.__proto__ === String.prototype);//true console.log(str instanceof String); //true //表达式二的指向 console.log(String .__proto__ === Function.prototype);//true console.log(String instanceof Function);//true //表达式三的指向 console.log(str .__proto__ === String.prototype);//true console.log(str .__proto__.__proto__ === String.prototype.__proto__);//true console.log(str .__proto__.__proto__ === Object.prototype);//true console.log(str .__proto__.__proto__.__proto__ === null);//true console.log(str instanceof Object);//true console.log(str instanceof Function);//false
Schauen wir uns eine weitere komplizierte Verwendung an
console.log(Object instanceof Object);//true console.log(Function instanceof Function);//true console.log(Number instanceof Number);//false console.log(String instanceof String);//false console.log(Function instanceof Object);//true console.log(Foo instanceof Function);//true console.log(Foo instanceof Foo);//false
Warum, warum ist das so? Sie müssen die folgende Bedeutung verstehen
1. Wie ist dieser Operator in der Sprachspezifikation definiert?
2. JavaScript-Prototyp-Vererbungsmechanismus
Objektinstanz von Objekt
// 为了方便表述,首先区分左侧表达式和右侧表达式 ObjectL = Object, ObjectR = Object; console.log(ObjectL instanceof ObjectR);//true
// 下面根据规范逐步推演 console.log(ObjectL.__proto__ === Function.prototype); //true console.log(ObjectL.__proto__.__proto__ === Object.prototype);//true
Funktionsinstanz der Funktion
FunctionL = Function, FunctionR = Function; console.log(FunctionL instanceof FunctionR);//true console.log(FunctionL.__proto__ === Function.prototype); //true <strong>Foo instanceof Foo </strong> function Foo(){} var foo = new Foo(); FooL = Foo, FooR = Foo; console.log(FooL instanceof FooR);//false console.log(FooL.__proto__ === Function.prototype );//true console.log(FooL.__proto__.__proto__ === Object.prototype );//true console.log(FooL.__proto__.__proto__.__proto__ === null );//true
In JavaScript gibt es kein Konzept der Mehrfachvererbung, genau wie in Java. Wenn Sie jedoch „declare“ verwenden, um eine Klasse in Dojo zu deklarieren, ist es zulässig, von mehreren Klassen zu erben
dojo.declare("Aoo",null,{}); dojo.declare("Boo",null,{}); dojo.declare("Foo",[Aoo,Boo],{}); var foo = new Foo(); console.log(foo instanceof Aoo);//true console.log(foo instanceof Boo);//false console.log(foo.isInstanceOf(Aoo));//true console.log(foo.isInstanceOf(Boo));//true
In einem Browser muss unser Skript möglicherweise zwischen mehreren Fenstern interagieren. Mehrere Fenster bedeuten mehrere globale Umgebungen, und unterschiedliche globale Umgebungen verfügen über unterschiedliche globale Objekte und daher unterschiedliche integrierte Typkonstruktoren. Dies kann einige Probleme verursachen. Beispielsweise gibt der Ausdruck [] Instanz von window.frames[0].Array „false“ zurück, da Array.prototype !== window.frames[0].Array.prototype ist. Sie müssen also Array.isArray(myObj) oder Object verwenden. Prototype.toString.call(myObj) === „[object Array]“, um zu bestimmen, ob myObj ein Array ist.
// 以下代码在版本 Google Chrome 45.0.2454.101 m 中测试通过 // Numbers console.log(37 instanceof Number);//false console.log( 3.14 instanceof Number);.//false console.log( Math.LN2 instanceof Number);//false console.log( Infinity instanceof Number);//false console.log( NaN instanceof Number); // false尽管NaN是"Not-A-Number"的缩写,意思是"不是一个数字" console.log( Number(1) instanceof Number); // false不要这样使用! // Strings console.log( "" instanceof String);// false console.log( "bla" instanceof String);// false console.log( ( 1) instanceof String); // falseconsole.log(返回的肯定是一个字符串 console.log( String("abc") instanceof String); // false 不要这样使用! // Booleans console.log( true instanceof Boolean);// false console.log( false instanceof Boolean);// false console.log( Boolean(true) instanceof Boolean); //false 不要这样使用! // Symbols console.log( Symbol() instanceof Symbol);// false console.log( Symbol("foo") instanceof Symbol);// false console.log( Symbol.iterator instanceof Symbol);// false // Undefined var blabla; //console.log( undefined instanceof Undefined);// Uncaught ReferenceError: Undefined is not defined //console.log( blabla instanceof Undefined); // Uncaught ReferenceError: Undefined is not defined console.log( undefined instanceof Object);// false console.log( blabla instanceof Object);// false // Objects 使用Array.isArray或者Object.prototype.toString.call方法可以从基本的对象中区分出数组类型 console.log( {a:1} instanceof Object);//true console.log( [1, 2, 4] instanceof Object);//true console.log( /^[a-zA-Z]{5,20}$/ instanceof Object);//true console.log( {name:'wenzi', age:25} instanceof Object);//true console.log( null === Object);//false // 下面的容易令人迷惑,不要这样使用! console.log( new Boolean(true) instanceof Object);//true console.log( new Number(1) instanceof Object);//true console.log( new Date() instanceof Object);//true console.log( new String("abc") instanceof Object);//true console.log( new Error() instanceof Object);//true // 函数 console.log( function(){} instanceof Function );//true console.log( Math.sin instanceof Function);//true
3. Konstruktor
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ösenObject.prototype.constructor gibt einen Verweis auf die Funktion zurück, die den Prototyp des Objekts erstellt hat. Beachten Sie, dass der Wert dieser Eigenschaft die Funktion selbst ist und nicht eine Zeichenfolge, die den Funktionsnamen enthält. Für primitive Werte (wie 1, true oder „test“) ist diese Eigenschaft schreibgeschützt und alle Objekte erben eine Konstruktor-Eigenschaft von ihrem Prototyp
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 >
function Person(){ } var Tom = new Person(); console.log(Tom.constructor === Person);//true
function Person(){ } function Student(){ } Student.prototype = new Person(); var John = new Student(); console.log(John.constructor==Student); // false console.log(John.constructor==Person); // true
function Type() { }; var types = [ new Array, [], new Boolean, true, // remains unchanged new Date, new Error, new Function, function(){}, Math, new Number, 1, // remains unchanged new Object, {}, new RegExp, /(?:)/, new String, "test" // remains unchanged ]; for(var i = 0; i < types.length; i++) { types[i].constructor = Type; types[i] = [ types[i].constructor, types[i] instanceof Type, types[i].toString() ]; }; console.log( types.join("\n") );
Verwenden Sie die toString()-Methode, um den Objekttyp zu erkennen
function Type() { }; var toString = Object.prototype.toString; console.log(toString.call(new Date) === '[object Date]');//true console.log(toString.call(new String) ==='[object String]');//true console.log(toString.call(new Function) ==='[object Function]');//true console.log(toString.call(Type) ==='[object Function]');//true console.log(toString.call('str') ==='[object String]');//true console.log(toString.call(Math) === '[object Math]');//true console.log(toString.call(true) ==='[object Boolean]');//true console.log(toString.call(/^[a-zA-Z]{5,20}$/) ==='[object RegExp]');//true console.log(toString.call({name:'wenzi', age:25}) ==='[object Object]');//true console.log(toString.call([1, 2, 3, 4]) ==='[object Array]');//true //Since JavaScript 1.8.5 console.log(toString.call(undefined) === '[object Undefined]');//true console.log(toString.call(null) === '[object Null]');//true
jquery bietet eine $.type-Schnittstelle, schauen Sie sich den Code an
var m = Object.prototype.toString //501行 E = {};//512行 isFunction: function(a) { //645行 return p.type(a) === "function" }, isArray: Array.isArray || function(a) { return p.type(a) === "array" } , isWindow: function(a) { return a != null && a == a.window }, isNumeric: function(a) { return !isNaN(parseFloat(a)) && isFinite(a) }, type: function(a) { return a == null ? String(a) : E[m.call(a)] || "object" }, isPlainObject: function(a) { if (!a || p.type(a) !== "object" || a.nodeType || p.isWindow(a)) return !1; try { if (a.constructor && !n.call(a, "constructor") && !n.call(a.constructor.prototype, "isPrototypeOf")) return !1 } catch (c) { return !1 } var d; for (d in a) ; return d === b || n.call(a, d) }, isEmptyObject: function(a) { var b; for (b in a) return !1; return !0 },