我前面的博客中介绍过基本数据类型和引用数据类型:基本类型是保存在栈内存中的简单数据段,也就是有单一字面量的值;引用数据类型指的是有多个值构成的对象。
typeof就是一个用来检测变量数据类型的操作符,主要用来检测基本数据类型。它可以判断一个变量是字符串、数值、布尔值还是undefined,但是如果检测的变量是引用数据类型,可以返回object或者function,但不能细致地分出是array还是RegExp。
而nstanceof主要的目的就是检测引用类型。
下面我们深入了解一下
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)+"
");
document.write ("typeof(NaN): "+typeof(NaN)+"
");
document.write ("typeof(Number.MIN_VALUE): "+typeof(Number.MIN_VALUE)+"
");
document.write ("typeof(Infinity): "+typeof(Infinity)+"
");
document.write ("typeof(true): "+typeof(true)+"
");
document.write ("typeof ([]): "+typeof([])+"
");
document.write ("typeof ({}): "+typeof({})+"
");
document.write ("typeof(window): "+typeof(window)+"
");
document.write ("typeof(Array()): "+typeof(new Array())+"
");
document.write ("typeof(document): "+typeof(document)+"
");
document.write ("typeof(null): "+typeof(null)+"
");
document.write ("typeof(function(){}): "+typeof(function(){})+"
");
document.write ("typeof(eval): "+typeof(eval)+"
");
document.write ("typeof(Date): "+typeof(Date)+"
");
document.write ("typeof (''): "+typeof('')+"
");
document.write ("typeof(\"123\"): "+typeof("123")+"
");
document.write ("typeof(sss): "+typeof(sss)+"
");
document.write ("typeof(undefined): "+typeof(undefined)+"
");
if(typeof a=="undefined"){document.write ("ok");}
</script>
<title>javascript类型测试</title>
</head>
<body>
</body>
</html>
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 )+ "
");
document.write ("{} instanceof Object: " + ({} instanceof Object )+ "
");
document.write ("/\d/ instanceof RegExp: " +( /\d/ instanceof RegExp) + "
");
document.write ("function(){} instanceof Object: " + (function(){} instanceof Object) +"
");
document.write ("function(){} instanceof Object: " + (function(){} instanceof Function) +"
");
document.write ("'' instanceof String: " + ('' instanceof String) +"
");
document.write ("1 instanceof Number: "+ (1 instanceof Number) +"
");
</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
在很多情况下,我们可以使用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(),可以解决跨框架问题。
这是对象的一个原生原型扩展函数,可以用来精确的区分数据类型