JavaScript中instanceof与typeof运算符的用法及区别详细解析


Posted in Javascript onNovember 19, 2013

JavaScript中的instanceof和typeof常被用来判断一个变量是什么类型的(实例),但它们的使用还是有区别的:

typeof 运算符
返回一个用来表示表达式的数据类型的字符串。

typeof expression ;

expression 参数是需要查找类型信息的任意表达式。

说明
typeof 是一个一元运算符,放在一个运算数之前。

typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: “number” ,“string”, “boolean”, “object” ,“function”, 和 “undefined.”

(而 ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。)

注释:

1、我们上面提到了ECMAScript的5种原始类型,在使用typeof操作符时,我们需要特别区分"对象类型"与"对象值"(字面值)的差别。例如Boolean 对象是 Boolean 原始类型的引用类型,而true和false则是Boolean对象的两个可能的对象值。我们可以把 ECMAScript的预定义对象(相对于其他语言中的类)看作是 相应类型的原始值的封装(或包装)。而ECMAScript的所有预定义对象又都是继承于Object对象。因此存在如下情况:

var testvar= new Number(68);

alert(typeof testvar);
//输出  "object"

testvar= 68;

alert(typeof testvar);
//输出  "number"

又如:
function Person(){}

document.write ("<br>typeof(Person):"+typeof(Person));

//function

var person = new Person();

document.write ("<br>typeof(person):"+typeof(person));

//object

注意:从传统意义上来说,ECMAScript 并不真正具有类。事实上,除了说明不存在类,在 ECMA-262 中根本没有出现“类”这个词。ECMAScript 定义了“对象定义”,逻辑上等价于其他程序设计语言中的类。

另外:这些预定义对象覆盖了Object 对象的 ValueOf() 方法,返回其原始值。而这些对象的所有属性和方法都可应用于相应类型的原始值上,因为它们是伪对象。

2、typeof 运算符对于 null 值会返回 "Object"。这实际上是 JavaScript 最初实现中的一个错误,然后被 ECMAScript 沿用了。现在,null 被认为是对象的占位符,从而解释了这一矛盾,但从技术上来说,它仍然是原始值。

提示:

1、值 undefined 并不同于未定义的值。但是,typeof 运算符并不真正区分这两种值。考虑下面的代码:

var oTemp;
alert(typeof oTemp);  //输出 "undefined"
alert(typeof oTemp2);  //输出 "undefined"

前面的代码对两个变量输出的都是 "undefined",即使只有变量 oTemp2 从未被声明过。如果对 oTemp2 使用除 typeof 之外的其他运算符的话,会引起错误,因为其他运算符只能用于已声明的变量上。

2、当函数无明确返回值时,返回的也是值 "undefined",如下所示:

function testFunc() {}
alert(testFunc() == undefined);  //输出 "true"3、类型Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。

alert(null == undefined);  //输出 "true"
尽管这两个值相等,但它们的含义不同:

undefined 是声明了变量但未对其初始化时赋予该变量的值 或 未声明过的变量(只能用于typeof,但作为赋值目标时编译器会自动将其声明为全局变量)。

null 则用于表示尚未存在的对象(即对象为空,或对象找不到)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

3、我们可以使用 typeof 来获取一个变量是否存在,如 if(typeof a!="undefined"){alert("ok")},而不要去使用 if(a) 因为如果 a 不存在(未声明)则会出错。

对于 Array,Null 等特殊对象使用 typeof 一律返回 object,这正是 typeof 的局限性。如果我们希望获取一个对象是否是数组,或判断某个变量是否是某个对象的实例则要选择使用instanceof。

instanceof 运算符
在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。

instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:

var oStringObject = new String("hello world");
alert(oStringObject instanceof String); //输出 "true"
这段代码问的是“变量 oStringObject 是否为 String 对象的实例?”oStringObject 的确是 String 对象的实例,因此结果是 "true"。尽管不像 typeof 方法那样灵活,但是在 typeof 方法返回 "object" 的情况下,instanceof 方法还是很有用的。

instanceof运算符

是一个二元运算符。返回一个 Boolean 值,指出对象是否是特定类的一个实例。

expression  instanceof class

参数

 expression  必选项。任意对象表达式。

 class

必选项。任意已定义的对象类。

说明
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true 。如果 object不是指定类的一个实例,或者 object 是 null ,则返回 false 。

用于判断一个变量是否某个对象的实例,

如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)会返回true。

注意:

关于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中的instanceof操作符的原理是什么?

学习js时,了解到在判断js中一个实例是否属于某一种类型时,可以使用instanceof操作符,比如function Person(){}

var person = new Person();  alert(person instanceof Person);//返回true

那么在执行instanceof这个操作时经过了怎样的判断,返回了true/false?

会不会是通过判断Person.prototype与person的内部指针[[prototype]]两者引用是否相同而得出结果的?

其实,凡是能在实例的"原型对象链"中找到该构造函数的prototype属性所指向的原型对象,就返回true。

而prototype根本就不是实例具有的属性(或者说实例的prototype属性为undefined),而是它原型对象中的属性,如果被篡改了,这个判断方法就不能正确返回了。

另外,能不能直接判断 person.constructor == Person来取得想要的结果呢?

我们做个测试,如下JavaScript代码:

function Person(name,sex){this.name=name;this.sex=sex;}
document.write ("<br>typeof Person:"+typeof Person);
document.write ("<br>typeof Person.prototype:"+typeof Person.prototype);
document.write ("<br>typeof Person.constructor:"+typeof Person.constructor);
var person = new Person();
document.write ("<br><br>var person = new Person();");
document.write ("<br>typeof person:"+typeof person);
document.write ("<br>typeof person.prototype:"+typeof person.prototype);
document.write ("<br>typeof person.constructor:"+typeof person.constructor);
document.write ("<br><br>Function.constructor:"+Function.constructor);
document.write ("<br><br>Function.prototype:"+Function.prototype);
document.write ("<br><br>Person.constructor:"+Person.constructor);
document.write ("<br><br>Person.prototype:"+Person.prototype);

document.write ("<br><br>person.constructor:"+person.constructor);
document.write ("<br><br>person.prototype:"+person.prototype);

输出如下:

typeof Person:function
typeof Person.prototype:object
typeof Person.constructor:function

var person = new Person();
typeof person:object
typeof person.prototype:undefined
typeof person.constructor:function

Function.constructor:function Function() { [native code] }
Function.prototype:function Empty() {}

Person.constructor:function Function() { [native code] }
Person.prototype:[object Object]

person.constructor:function Person(name,sex){this.name=name;this.sex=sex;}
person.prototype:undefined

和Function类似,Number()为Number对象的构造函数,Number()用于将其参数转换为数字number类型,并返回转换结果(若不能转换则返回NaN)。

在JavaScript中constructor较少使用,variable.constructor返回其对象类的构造函数的字符串表示。

那么在JavaScript中判断数据类型时,我们可以使用以下方式来得到其详细数据类型:

if((typeof a=="object") && (a.constructor==Array)){

}

注意:constructor只能对已有变量进行判断,而typeof则可对未声明变量或空对象进行判断(返回undefined)。

Javascript 相关文章推荐
关于JavaScript的gzip静态压缩方法
Jan 05 Javascript
jquery xMarquee实现文字水平无缝滚动效果
Apr 29 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
Nov 23 Javascript
jQuery实现简洁的导航菜单效果
Nov 23 Javascript
jQuery获取同级元素的简单代码
Jul 09 Javascript
jQuery Easyui datagrid行内实现【添加】、【编辑】、【上移】、【下移】
Dec 19 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
Dec 26 Javascript
浅谈javascript的闭包
Jan 23 Javascript
jQuery简单绑定单个事件的方法示例
Jun 10 jQuery
深入理解node.js http模块
Jan 24 Javascript
Node.js 的 GC 机制详解
Jun 03 Javascript
js实现for循环跳过undefined值示例
Jul 02 Javascript
Query中click(),bind(),live(),delegate()的区别
Nov 19 #Javascript
Js 去掉字符串中的空格(实现代码)
Nov 19 #Javascript
JS正则验证邮箱的格式详细介绍
Nov 19 #Javascript
js判读浏览器是否支持html5的canvas的代码
Nov 18 #Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
Nov 18 #Javascript
基于javascript滚动图片具体实现
Nov 18 #Javascript
点击页面其它地方隐藏该div的两种思路
Nov 18 #Javascript
You might like
PHP循环语句笔记(foreach,list)
2011/11/29 PHP
解析PHP工厂模式的好处
2013/06/18 PHP
解析php类的注册与自动加载
2013/07/05 PHP
php 在字符串指定位置插入新字符的简单实现
2016/06/28 PHP
THINKPHP3.2使用soap连接webservice的解决方法
2017/12/13 PHP
Jquery图片滚动与幻灯片的实例代码
2013/04/08 Javascript
Node.js模块封装及使用方法
2016/03/06 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
2016/09/01 Javascript
JavaScript代码执行的先后顺序问题
2017/10/29 Javascript
js动态添加表格逐行添加、删除、遍历取值的实例代码
2018/01/25 Javascript
在 webpack 中使用 ECharts的实例详解
2018/02/05 Javascript
详解webpack4多入口、多页面项目构建案例
2018/05/25 Javascript
基于AngularJs select绑定数字类型的问题
2018/10/08 Javascript
js和jquery判断数据类型的4种方法总结
2020/08/28 jQuery
[03:09]2014DOTA2国际邀请赛 赛场上的美丽风景线 中国Coser也爱DOTA2
2014/07/20 DOTA
[58:15]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 NB vs Liquid
2018/04/02 DOTA
Python中的True,False条件判断实例分析
2015/01/12 Python
Python中datetime常用时间处理方法
2015/06/15 Python
python实现简单神经网络算法
2018/03/10 Python
PHP实现发送和接收JSON请求
2018/06/07 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
Python2 与Python3的版本区别实例分析
2020/03/30 Python
python os模块在系统管理中的应用
2020/06/22 Python
Python+OpenCV图像处理——打印图片属性、设置存储路径、调用摄像头
2020/10/22 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
python如何获得list或numpy数组中最大元素对应的索引
2020/11/16 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
把富文本的回车转为br标签
2019/08/09 HTML / CSS
中国最大的潮流商品购物网站:YOHO!BUY有货
2017/01/07 全球购物
智能旅行箱:Horizn Studios
2018/04/30 全球购物
企业宣传策划方案
2014/05/29 职场文书
公司授权委托书范本
2014/09/18 职场文书
软件项目经理岗位职责
2015/04/01 职场文书
离职员工给领导和同事的感谢信
2015/11/03 职场文书
python 爬取哔哩哔哩up主信息和投稿视频
2021/06/07 Python