javascript之typeof、instanceof操作符使用探讨


Posted in Javascript onMay 19, 2013

写javascirpt代码时,typeof和instanceof这两个操作符时不时就会用到,堪称必用。但是!使用它们总是不能直接的得到想要的结果,非常纠结,普遍的说法认为“这两个操作符或许是javascript中最大的设计缺陷,因为几乎不可能从他们那里得到想要的结果”
typeof
说明:typeof返回一个表达式的数据类型的字符串,返回结果为js基本的数据类型,包括number,boolean,string,object,undefined,function。
从说明来看,貌似没什么问题。

下面的代码写了一个数值变量,typeof后的结果是"number"。

var a = 1; 
console.log(typeof(a)); //=>number

如果用Number类型的构造函数new一个变量的话,typeof后的结果是"object"。
var a = new Number(1); 
console.log(typeof(a)); //=>object

上面的这两个输出结果看似没啥问题,这一点从书上看来是理所当然的事情,因为javascript就是这么设计的。

但是!问题就在于既然调用了typeof就应该准确返回一个变量的类型,不管是直接用值创建的还是用类型的构造函数创建的,否则!我还用你做啥!
那么对于:

var a = 1; 
var b = new Number(1);

a和b变量的类型准确的说来都应该是Number才是想要的结果。
而准确的类型信息保存在变量的内部属性 [[Class]] 的值中,通过使用定义在 Object.prototype 上的方法 toString来获取。

获取类型信息:

var a = 1; 
var b = new Number(1); 
console.log(Object.prototype.toString.call(a)); 
console.log(Object.prototype.toString.call(b));

输出:
[object Number] 
[object Number]

是不是已经很直接了,我们稍微处理一下,得到直接结果:
var a = 1; 
var b = new Number(1); 
console.log(Object.prototype.toString.call(a).slice(8,-1)); 
console.log(Object.prototype.toString.call(b).slice(8,-1));

输出:
Number
Number
这就是想要的结果。
为了更好的使用,我们封装一个方法,用来判断某个变量是否是某种类型:
function is(obj,type) { 
var clas = Object.prototype.toString.call(obj).slice(8, -1); 
return obj !== undefined && obj !== null && clas === type; 
}

定义一些变量做过测试,先来看看它们的typeof输出:
var a1=1; 
var a2=Number(1); 
var b1="hello"; 
var b2=new String("hello"); 
var c1=[1,2,3]; 
var c2=new Array(1,2,3); 
console.log("a1's typeof:"+typeof(a1)); 
console.log("a2's typeof:"+typeof(a2)); 
console.log("b1's typeof:"+typeof(b1)); 
console.log("b2's typeof:"+typeof(b2)); 
console.log("c1's typeof:"+typeof(c1)); 
console.log("c2's typeof:"+typeof(c2)); 
输出: 
a1's typeof:number 
a2's typeof:object 
b1's typeof:string 
b2's typeof:object 
c1's typeof:object 
c2's typeof:object

我们再用新作的函数是一下:
console.log("a1 is Number:"+is(a1,"Number")); 
console.log("a2 is Number:"+is(a2,"Number")); 
console.log("b1 is String:"+is(b1,"String")); 
console.log("b2 is String:"+is(b2,"String")); 
console.log("c1 is Array:"+is(c1,"Array")); 
console.log("c2 is Array:"+is(c2,"Array")); 
输出: 
a1 is Number:true 
a2 is Number:true 
b1 is String:true 
b2 is String:true 
c1 is Array:true 
c2 is Array:true

注:typeof也不是无用,实际用处是用来检测一个变量是否已经定义或者是否已经赋值。
instanceof
说明:判断一个对象是否为某一数据类型,或一个变量是否为一个对象的实例。
instanceof 操作符用来比较两个内置类型的变量时一样力不从心,同样会对结果不满意。
console.log("abc" instanceof String); // false 
console.log("abc" instanceof Object); // false 
console.log(new String("abc") instanceof String); // true 
console.log(new String("abc") instanceof Object); // true

只有在比较自定义的对象时才准确反映关系。
function Person() {} 
function Man() {} 
Man.prototype = new Person(); 
console.log(new Man() instanceof Man); // true 
console.log(new Man() instanceof Person); // true
Javascript 相关文章推荐
扩展String功能方法
Sep 22 Javascript
js中将String转换为number以便比较
Jul 08 Javascript
2014年最火的Node.JS后端框架推荐
Oct 27 Javascript
js解决movebox移动问题
Mar 29 Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
Feb 15 Javascript
详解Angular2中Input和Output用法及示例
May 21 Javascript
JavaScript正则表达式的贪婪匹配和非贪婪匹配
Sep 05 Javascript
详解vue文件中使用echarts.js的两种方式
Oct 18 Javascript
js回调函数原理与用法案例分析
Mar 04 Javascript
RxJS在TypeScript中的简单使用详解
Apr 13 Javascript
解决vue 使用setTimeout,离开当前路由setTimeout未销毁的问题
Jul 21 Javascript
Postman如何实现参数化执行及断言处理
Jul 28 Javascript
关于innerHTML后丢失动态绑定的EVENT问题解决方法
May 19 #Javascript
JS特殊函数(Function()构造函数、函数直接量)区别介绍
May 19 #Javascript
JavaScript中几个重要的属性(this、constructor、prototype)介绍
May 19 #Javascript
js函数中onmousedown和onclick的区别和联系探讨
May 19 #Javascript
下拉菜单点击实现连接跳转功能的js代码
May 19 #Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
May 19 #Javascript
固定背景实现的背景滚动特效示例分享
May 19 #Javascript
You might like
PHP获取windows登录用户名的方法
2014/06/24 PHP
php简单实现发送带附件的邮件
2015/06/10 PHP
Laravel执行migrate命令提示:No such file or directory的解决方法
2016/03/16 PHP
Yii2.0实现的批量更新及批量插入功能示例
2019/01/29 PHP
ThinkPHP5.0框架验证码功能实现方法【基于第三方扩展包】
2019/03/11 PHP
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
javascript正则表达式参数/g与/i及/gi的使用指南
2014/08/27 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
Bootstrap学习系列之使用 Bootstrap Typeahead 组件实现百度下拉效果
2016/07/07 Javascript
AngularJS表单基本操作
2017/01/09 Javascript
bootstrap如何让dropdown menu按钮式下拉框长度一致
2017/04/10 Javascript
详解在网页上通过JS实现文本的语音朗读
2019/03/28 Javascript
微信小程序基于canvas渐变实现的彩虹效果示例
2019/05/03 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
js点击事件的执行过程实例分析【冒泡与捕获】
2020/04/11 Javascript
[42:04]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#3Secret VS OG第一局
2016/03/03 DOTA
[51:32]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python读取html中指定元素生成excle文件示例
2014/04/03 Python
Python的collections模块中的OrderedDict有序字典
2016/07/07 Python
如何在Python函数执行前后增加额外的行为
2016/10/20 Python
Python计算一个给定时间点前一个月和后一个月第一天的方法
2018/05/29 Python
python3使用SMTP发送HTML格式邮件
2018/06/19 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
Python 元组拆包示例(Tuple Unpacking)
2019/12/24 Python
CSS3中设置3D变形的transform-style属性详解
2016/05/23 HTML / CSS
HTML5 Canvas像素处理使用接口介绍
2012/12/02 HTML / CSS
奇怪的鱼:Weird Fish
2018/03/18 全球购物
巴西备受欢迎的服装和生活方式品牌:FARM Rio
2020/02/04 全球购物
Kappa英国官方在线商店:服装和运动器材
2020/11/22 全球购物
大学生通用个人自我评价
2014/04/27 职场文书
购房意向书
2014/08/30 职场文书
Django中的JWT身份验证的实现
2021/05/07 Python
pytorch 如何使用amp进行混合精度训练
2021/05/24 Python
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
nginx搭建NFS网络文件系统
2022/04/14 Servers
python获取带有返回值的多线程
2022/05/02 Python