Home > Article > Web Front-end > Defects and optimizations of JavaScript type detection typeof and instanceof_javascript skills
In JavaScript, typeof and instanceof are two common methods used to determine data types. The purpose of this article is to introduce these two methods to analyze their shortcomings and propose optimization solutions.
typeof
-------------------------------------------------- ----------------------------------
typeof returns a string of the data type of an expression. The returned result is the basic data type in JavaScript, including: number, boolean, string, object, undefined, function and other 6 data types.
typeof 100; //number typeof (1==1); //boolean typeof 'onepixel'; //string typeof {} ; //object typeof onepixel; // undefined typeof parseInt; // function typeof [];//object typeof new Date(); //object
It can be seen that typeof can accurately determine basic data types other than object, but it cannot distinguish specific types of object types, such as Array, Date and custom classes.
instanceof
-------------------------------------------------- ----------------------------------
instanceof is intended to determine whether A is an instance object of B. The expression is: A instanceof B. If A is an instance of B, it returns true, otherwise it returns false. What needs special attention here is: instanceof detects the prototype, so how does it detect it? We use a piece of pseudo code to simulate its internal execution process:
instanceof (A,B) = { var L = A.__proto__; var R = B.prototype; if(L === R) { //A的内部属性__proto__指向B的原型对象 return true; } return false; }
As can be seen from the above process, when A's __proto__ points to B's prototype, A is considered to be an instance object of B. Let's look at a few more examples:
[] instanceof Array; //true {} instanceof Object;//true new Date() instanceof Date;//true function Person(){}; new Person() instanceof Person; [] instanceof Object; //true new Date() instanceof Object;//tru new Person instanceof Object;//true
From the above example, we found that although instanceof can correctly determine that [] is an instance object of Array, it cannot distinguish that [] is not an instance object of Object. Why? We need to start with the prototype chain of javascript. First, let’s analyze the relationship between [], Array, and Object. Judging from instanceof, we can conclude: [].__proto__ ->Array.prototype, and Array.prototype.__proto__ points to Object.prototype, Object. prototype.__proto__ points to null, marking the end of the prototype chain. (ps: Regarding the JS prototype chain, please read: A brief discussion of javascript prototypes and prototype chains) Therefore, [], Array, and Object form a prototype chain:
As can be seen from the prototype chain, the __proto__ of [] ultimately points to Object.prototype. Similar new Date() and new Person() will also form such a prototype chain. Therefore, we cannot use instanceof completely. Accurately determine the specific data type of the object class.
Optimization plan
-------------------------------------------------- ----------------------------------
For this problem, when reading the jQuery source code, I found a better solution. Since there are mutual calls between the source codes, it is difficult to read and understand. Therefore, it was organized and encapsulated according to its ideas. The code is as follows:
(function(){ var class2type = {}; var typeList = "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ); typeList.eachEach(function(item){ class2type[ "[object " + item + "]" ] = item.toLowerCase(); } return { getObjType:function(obj) { if ( obj == null ) { return obj + ""; } if(typeof obj === "object" || typeof obj === "function"){ class2type[ toString.call( obj ) ] || "object" }else { return typeof obj; } } } })()
In JavaScript, typeof and instanceof are often used to determine whether a variable is empty or what type it is. But there are still differences between them:
typeof
typeof is a unary operation, placed before an operand, and the operand can be of any type.
The return value is a string describing the type of the operand. typeof generally can only return the following results:
number,boolean,string,function,object,undefined. We can use typeof to get whether a variable exists, such as if(typeof a!="undefined"){alert("ok")}, instead of using if(a) because if a does not exist (undeclared), it will If an error occurs, using typeof for special objects such as Array and Null will always return object. This is the limitation of typeof.
A small example from the Internet:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script language="javascript" type="text/javascript"> document.write ("typeof(1): "+typeof(1)+"<br>"); document.write ("typeof(NaN): "+typeof(NaN)+"<br>"); document.write ("typeof(Number.MIN_VALUE): "+typeof(Number.MIN_VALUE)+"<br>"); document.write ("typeof(Infinity): "+typeof(Infinity)+"<br>"); document.write ("typeof(\"123\"): "+typeof("123")+"<br>"); document.write ("typeof(true): "+typeof(true)+"<br>"); document.write ("typeof(window): "+typeof(window)+"<br>"); document.write ("typeof(Array()): "+typeof(new Array())+"<br>"); document.write ("typeof(function(){}): "+typeof(function(){})+"<br>"); document.write ("typeof(document): "+typeof(document)+"<br>"); document.write ("typeof(null): "+typeof(null)+"<br>"); document.write ("typeof(eval): "+typeof(eval)+"<br>"); document.write ("typeof(Date): "+typeof(Date)+"<br>"); document.write ("typeof(sss): "+typeof(sss)+"<br>"); document.write ("typeof(undefined): "+typeof(undefined)+"<br>") </script> <title>javascript类型测试</title> </head> <body> </body> </html>
instanceof
instance:实例,例子
a instanceof b?alert("true"):alert("false"); //a是b的实例?真:假
instanceof 用于判断一个变量是否某个对象的实例,如 var a=new Array();alert(a instanceof Array); 会返回 true,同时 alert(a instanceof Object) 也会返回 true;这是因为 Array 是 object 的子类。再如:function test(){};var a=new test();alert(a instanceof test) 会返回
谈到 instanceof 我们要多插入一个问题,就是 function 的 arguments,我们大家也许都认为 arguments 是一个 Array,但如果使用 instaceof 去测试会发现 arguments 不是一个 Array 对象,尽管看起来很像。
另外:
测试 var a=new Array();if (a instanceof Object) alert('Y');else alert('N');
得'Y'
但 if (window instanceof Object) alert('Y');else alert('N');
得'N'
所以,这里的 instanceof 测试的 object 是指 js 语法中的 object,不是指 dom 模型对象。
使用 typeof 会有些区别
alert(typeof(window)) 会得 object
大家知道JavaScript中判断函数参数类型是用typeof还是instanceof吗?
typeof只能判断js已有的几个类型,如function,object,number。
而instanceof可以判断对象是由哪个函数实例化出来的,如:
var a=function(x){}; var b=function(x){}; var c=new a(1); var d=new a(2);
c instanceof a为true而d instanceof b为false。
而用typeof c和typeof d的结果都是object
“判断函数参数类型”需要根据你的需求来选择用哪个。