我前面的博客中介绍过基本数据类型和引用数据类型:基本类型是保存在栈内存中的简单数据段,也就是有单一字面量的值;引用数据类型指的是有多个值构成的对象。
typeof就是一个用来检测变量数据类型的操作符,主要用来检测基本数据类型。它可以判断一个变量是字符串、数值、布尔值还是undefined,但是如果检测的变量是引用数据类型,可以返回object或者function,但不能细致地分出是array还是RegExp。
而nstanceof主要的目的就是检测引用类型。
下面我们深入了解一下
typeof和instanceof的区别:
1.typeof:
typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型。
主要用于判断数据是不是基本数据类型:
String、Number、Object、Null、Undefined、Boolean,但是无法判断出function、array、regExp
返回值是一个字符串,该字符串说明运算数的类型。
typeof 一般只能返回如下几个结果:
number、boolean、string、function、object、undefined。
甚至我们可以使用 typeof 来判断一个变量是否存在,
如 if(typeof a == “undefined”){document.write (“ok”);},而不需要去使用 if(a) ,因为如果 a 不存在(未声明)则会出错,对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。
看一下代码示例:
<!DOCTYPE html> <html> <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(true): "+typeof(true)+"<br>"); document.write ("typeof ([]): "+typeof([])+"<br>"); document.write ("typeof ({}): "+typeof({})+"<br>"); document.write ("typeof(window): "+typeof(window)+"<br>"); document.write ("typeof(Array()): "+typeof(new Array())+"<br>"); document.write ("typeof(document): "+typeof(document)+"<br>"); document.write ("typeof(null): "+typeof(null)+"<br>"); document.write ("typeof(function(){}): "+typeof(function(){})+"<br>"); document.write ("typeof(eval): "+typeof(eval)+"<br>"); document.write ("typeof(Date): "+typeof(Date)+"<br>"); document.write ("typeof (''): "+typeof('')+"<br>"); document.write ("typeof(\"123\"): "+typeof("123")+"<br>"); document.write ("typeof(sss): "+typeof(sss)+"<br>"); document.write ("typeof(undefined): "+typeof(undefined)+"<br>"); if(typeof a=="undefined"){document.write ("ok");} </script> <title>javascript类型测试</title> </head> <body> </body> </html>
运行结果:
2.instanceof:
instanceof主要的目的是用来检测引用类型,返回值只有true和false,可以用来判断某个构造函数的prototype属性是否存在于另外一个要检测对象的原型链上。 这里我们可以先不去理会原型
看如下代码示例:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script language="javascript" type="text/javascript"> document.write ("[] instanceof Array: " + ([] instanceof Array )+ "<br>"); document.write ("{} instanceof Object: " + ({} instanceof Object )+ "<br>"); document.write ("/\d/ instanceof RegExp: " +( /\d/ instanceof RegExp) + "<br>"); document.write ("function(){} instanceof Object: " + (function(){} instanceof Object) +"<br>"); document.write ("function(){} instanceof Object: " + (function(){} instanceof Function) +"<br>"); document.write ("'' instanceof String: " + ('' instanceof String) +"<br>"); document.write ("1 instanceof Number: "+ (1 instanceof Number) +"<br>"); </script> <title>javascript类型测试</title> </head> <body> </body> </html>
运行结果如下:
例如我们要判断a是否是b实例?可以使用a instanceof b?alert(“true”):alert(“false”);来判断
instanceof 用于判断一个变量是否某个对象的实例
如 var a=new Array();alert(a instanceof Array); 会返回 true
同时 alert(a instanceof Object) 也会返回 true;
这是因为 Array 是 object 的子类。
谈到 instanceof 我们要多插入一个问题,就是 function 的 arguments,我们大家也许都认为 arguments 是一个 Array,但如果使用 instanceof 去测试会发现 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
3.Object.prototype.toString
在很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。例如很多JavaScript框架就是使用这两种方法来判断对象是否为数组类型。 但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框架(iframe)中创建的数组不会相互共享其prototype属性
<script> window.onload=function(){ var iframe_arr=new window.frames[0].Array; alert(iframe_arr instanceof Array); // false alert(iframe_arr.constructor == Array); // false } </script>
而跨原型链调用toString()方法:Object.prototype.toString(),可以解决上面的跨框架问题。
这是对象的一个原生原型扩展函数,用来精确的区分数据类型
当Object.prototype.toString(o)执行后,会执行以下步骤:
1)获取对象o的class属性。
2)连接字符串:"[object “+结果(1)+”]"
3)返回 结果
Object.prototype.toString.call([]); // 返回 “[object Array]”
Object.prototype.toString.call(/reg/ig); // 返回 “[object RegExp]”
并且我们会发现,typeof来判断数据类型其实并不准确。比如数组、正则、日期、对象的typeof返回值都是object,这就会造成一些误差。
所以在typeof判断类型的基础上,我们还需要利用Object.prototype.toString方法来进一步判断数据类型。
我们来看一下代码:
<script language="javascript" type="text/javascript"> var type=Object.prototype.toString console.log(type.call(''));//object String console.log(type.call([]));//object Array console.log(type.call({}));//object Object console.log(type.call(false));//object Boolean console.log(type.call());//object Null console.log(type.call(undefined));//object Undefined console.log(type.call(function(){}));//object Function //判断方式 console.log(type.call('')=="[object String]");//true </script>
运行结果:
总结起来就是:
typeof和instanceof都是用来检测变量类型的操作符,二者的区别在于
typeof是判断变量是什么基本类型的; instanceof是判断对象到底是什么类型的;
跨原型链调用toString()方法:Object.prototype.toString(),可以解决跨框架问题。
这是对象的一个原生原型扩展函数,可以用来精确的区分数据类型