JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法

我前面的博客中介绍过基本数据类型和引用数据类型:基本类型是保存在栈内存中的简单数据段,也就是有单一字面量的值;引用数据类型指的是有多个值构成的对象。

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)+"
"
); 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>

运行结果:
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法_第1张图片


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 )+ "
"
); 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>

运行结果如下:
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法_第2张图片

例如我们要判断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>

运行结果:
JavaScript总结:typeof与instanceof的区别,及Object.prototype.toString()方法_第3张图片


总结起来就是:

typeof和instanceof都是用来检测变量类型的操作符,二者的区别在于

typeof是判断变量是什么基本类型的; instanceof是判断对象到底是什么类型的;

跨原型链调用toString()方法:Object.prototype.toString(),可以解决跨框架问题。
这是对象的一个原生原型扩展函数,可以用来精确的区分数据类型

你可能感兴趣的:(前端)