Heim > Web-Frontend > js-Tutorial > Sprechen Sie kurz über die Typbeurteilung in Javascript_Javascript-Fähigkeiten

Sprechen Sie kurz über die Typbeurteilung in Javascript_Javascript-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:36:05
Original
1144 Leute haben es durchsucht

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

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

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

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

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

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


// 下面根据规范逐步推演
console.log(ObjectL.__proto__ === Function.prototype); //true
console.log(ObjectL.__proto__.__proto__ === Object.prototype);//true
Nach dem Login kopieren

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

Nach dem Login kopieren
Anwendung von „instanceof“ im Dojo-Vererbungsmechanismus

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
Nach dem Login kopieren
Instanz von und mehreren globalen Objekten (Interaktion zwischen mehreren Frames oder mehreren Fenstern)

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
Nach dem Login kopieren
Hinweis: Undefiniert und Null werden als Objekttypen erkannt, da es in js keine globalen Typen von Undefiniert und Null gibt und Zahl, Zeichenfolge und Boolescher Wert ihre Typen nicht erkennen können

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ösen

Object.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
Nach dem Login kopieren
Beachten Sie jedoch, dass das Konstruktorattribut geändert werden kann, was dazu führt, dass die erkannten Ergebnisse falsch sind

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
Ändern Sie den Wert der Konstruktoreigenschaft dieses Objekts

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,
  /(&#63;:)/,
  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") );
Nach dem Login kopieren
Außer undefiniert und null kann der Typ anderer Variablentypen mithilfe des Konstruktors bestimmt werden

4. Der universelle Object.prototype.toString.call

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
Nach dem Login kopieren
Anbei finden Sie die Beurteilungsfunktion. Wie viel wissen Sie über die Datentypen in Javascript?

5. Implementierung von jquery jquery: „1.8.2“,

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 &#63; 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
},
Nach dem Login kopieren
Es ist ersichtlich, dass jquery mithilfe von Object.prototype.toString.call implementiert wird
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