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 相关文章推荐
JavaScript 核心参考教程 内置对象
Oct 13 Javascript
JavaScript实用技巧(一)
Aug 16 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
Mar 28 Javascript
js中根据字数截取字符串,不能截断url
Jan 12 Javascript
text-align:justify实现文本两端对齐 兼容IE
Aug 19 Javascript
Bootstrap按钮下拉菜单组件详解
May 10 Javascript
提高Node.js性能的应用技巧分享
Aug 10 Javascript
vue-router 路由基础的详解
Oct 17 Javascript
jQuery实现获取选中复选框的值实例详解
Jun 28 jQuery
vue自定v-model实现表单数据双向绑定问题
Sep 03 Javascript
js仿淘宝放大镜效果
Dec 28 Javascript
详解jQuery的核心函数和事件处理
Feb 18 jQuery
关于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传输数据的代码
2007/11/13 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
2013/07/01 PHP
PHP中date与gmdate的区别及默认时区设置
2014/05/12 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
PHP把MSSQL数据导入到MYSQL的方法
2014/12/27 PHP
php 微信开发获取用户信息如何实现
2016/12/13 PHP
laravel返回统一格式错误码问题
2019/11/04 PHP
多浏览器兼容的获取元素和鼠标的位置的js代码
2009/12/15 Javascript
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
jquery与google map api结合使用 控件,监听器
2010/03/04 Javascript
jquery append()方法与html()方法的区别及使用介绍
2014/08/01 Javascript
jQuery 3.0十大新特性
2016/07/06 Javascript
很棒的js Tab选项卡切换效果
2016/08/30 Javascript
详解利用Angular实现多团队模块化SPA开发框架
2017/11/27 Javascript
解决vue-cli创建项目的loader问题
2018/03/13 Javascript
vue引入js数字小键盘的实现代码
2018/05/14 Javascript
解决layui前端框架 form表单,table表等内置控件不显示的问题
2018/08/19 Javascript
vue组件中的样式属性scoped实例详解
2018/10/30 Javascript
学习使用ExpressJS 4.0中的新Router的用法
2018/11/06 Javascript
在vue中封装的弹窗组件使用队列模式实现方法
2020/07/23 Javascript
创建与框架无关的JavaScript插件
2020/12/01 Javascript
[02:38]DOTA2亚洲邀请赛小组赛精彩集锦:Wings完美团击溃对手
2017/03/29 DOTA
centos系统升级python 2.7.3
2014/07/03 Python
python进阶教程之函数对象(函数也是对象)
2014/08/30 Python
pyspark操作MongoDB的方法步骤
2019/01/04 Python
Django集成CAS单点登录的方法示例
2019/06/10 Python
聊聊python中的异常嵌套
2020/09/01 Python
HTML5 离线应用之打造零请求、无流量网站的解决方法
2013/04/25 HTML / CSS
ProBikeKit英国:在线公路自行车之家
2017/02/10 全球购物
广州足迹信息技术有限公司Java软件工程师试题
2014/02/15 面试题
自我评价范文分享
2014/01/04 职场文书
开学典礼决心书
2014/03/11 职场文书
个人融资协议书范本两则
2014/10/15 职场文书
2014年员工工作总结范文
2014/11/18 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
golang interface判断为空nil的实现代码
2021/04/24 Golang