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 相关文章推荐
jQuery中使用了document和window哪些属性和方法小结
Sep 13 Javascript
javascript基于DOM实现权限选择实例分析
May 14 Javascript
JavaScript简单遍历DOM对象所有属性的实现方法
Oct 21 Javascript
AngularJS基础 ng-focus 指令简单示例
Aug 01 Javascript
Vue表单验证插件的制作过程
Apr 01 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
Dec 13 Javascript
解决vue 引入子组件报错的问题
Sep 06 Javascript
15分钟深入了解JS继承分类、原理与用法
Jan 19 Javascript
JS实现的全选、全不选及反选功能【案例】
Feb 19 Javascript
Element的el-tree控件后台数据结构的生成以及方法的抽取
Mar 05 Javascript
Element InfiniteScroll无限滚动的具体使用方法
Jul 27 Javascript
vue自定义组件实现双向绑定
Jan 13 Vue.js
关于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
用javascript实现计算两个日期的间隔天数
2007/08/14 Javascript
javascript获取当前ip的代码
2009/05/10 Javascript
在js文件中如何获取basePath处理js路径问题
2013/07/10 Javascript
json数据与字符串的相互转化示例
2013/09/18 Javascript
jQuery中:header选择器用法实例
2014/12/29 Javascript
javascript实现字符串反转的方法
2015/02/05 Javascript
JavaScript使用二分查找算法在数组中查找数据的方法
2015/04/07 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
2016/01/12 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
Vue.js每天必学之构造器与生命周期
2016/09/05 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
php 修改密码实现代码
2017/05/24 Javascript
微信小程序页面滑动屏幕加载数据效果
2020/11/16 Javascript
详解vue-cli3使用
2018/08/14 Javascript
基于Vue.js与WordPress Rest API构建单页应用详解
2019/09/16 Javascript
javascript网页随机点名实现过程解析
2019/10/15 Javascript
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
Python日志模块logging简介
2015/04/13 Python
Python对数据库操作
2016/03/28 Python
Python设置默认编码为utf8的方法
2016/07/01 Python
利用Python查看微信共同好友功能的实现代码
2019/04/24 Python
python实现回旋矩阵方式(旋转矩阵)
2019/12/04 Python
HTML table 表格边框的实现思路
2019/10/12 HTML / CSS
水芝澳美国官网:H2O Plus
2016/10/15 全球购物
接口中的方法可以是abstract的吗
2015/07/23 面试题
计算机网络毕业生自荐信
2013/10/01 职场文书
求职信怎么写范文
2014/05/26 职场文书
党员教师批评与自我批评发言稿
2014/10/15 职场文书
夫妻分居协议书范本
2014/11/28 职场文书
苏州园林导游词
2015/02/03 职场文书
个人专业技术总结
2015/03/05 职场文书
党员读书活动心得体会
2016/01/14 职场文书
大学学生会主席竞选稿怎么写?
2019/08/19 职场文书
JAVA API 实用类 String详解
2021/10/05 Java/Android
详解Redis在SpringBoot工程中的综合应用
2021/10/16 Redis
mysql使用instr达到in(字符串)的效果
2022/04/03 MySQL