如何检测JavaScript的各种类型


Posted in Javascript onJuly 30, 2016

一、先介绍下5种原始类型

JavaScript中5种原始类型为stringnumberbooleanundefinednull

var name = "Jack";
var age = 32;
var single = false;
var app;  //undefined

console.log(typeof name);  //string
console.log(typeof age);  //number
console.log(typeof single); //boolean
console.log(typeof app);  //undefined
console.log(typeof null);  //object

发现除null外的其他4种基本类型均可以用typeof来识别:

if(typeof name === "string") { name += "Zhang"; }
if(typeof age === "number") { age++; }
if(typeof single === "boolean" && single) { … }
if(typeof app === "undefined") { app = {}; }

因为typeof null会得到object,所以直接用===来检测null:

if(el === null) { … }

二、对象

JavaScript的对象包括内置对象(Date,RegExp ,Error等)和自定义对象

(注意,Function和Array虽然也都是内置对象,但下一节单独讲)

对象不能像基本类型那样用typeof来检测了,因为检测出来的结果都是object

console.log(typeof new Date());  //object
console.log(typeof new RegExp()); //object
console.log(typeof new Error());  //object
console.log(typeof new Person()); //用typeof检测出自定义对象也是object

要改用instanceof来检测:

var date = new Date();
var reg = new RegExp();
var err = new Error();
var me = new Person();

if(date instanceof Date) {  //检测日期
  year = date.getFullYear(); 
}
if(reg instanceof RegExp) {  //检测正则表达式
  reg.test(...); 
}
if(err instanceof Error) {  //检测异常
  throw err; 
}
if(me instanceof Person) {  //检测自定义对象
  ... 
}

但自定义对象有个问题,假设浏览器frameA里和frameB里都定义了Person。 frameA里定义了me对象,用me instanceof Person检测出来为true。但当自定义对象me传给frameB后,在frameB里instanceof会是false。

本节一开头就说了,Function和Array虽然也都是内置对象,但留到下一节讲。原因就是Function和Array也有和自定义对象相同的上述问题。因此Function和Array一般不用instanceof

三、Function

上面说了用instanceof检测Function不能跨frame。因此用typeof来检测,它可跨frame:

var func = function(){};
if(typeof func === 'function') { … }

但IE8以前用typeof来检测DOM系函数会得到object,因此IE8以前改用in:

console.log(typeof document.getElementById);    //object,不是function
console.log(typeof document.getElementsByTagName); //object,不是function
console.log(typeof document.createElement);     //object,不是function

//IE8以前的IE浏览器,要改用in来检测是否支持DOM函数
if("getElementById" in document) { … }    
if("getElementsByTagName" in document) { … }
if("createElement" in document) { … }

四、Array

上面说了用instanceof检测Array不能跨frame。ES5之前都自定义检测方法。其中最精确的方法:依赖Array的toString会返回固定字符串”[Object Array]”的事实来检测

function isArray(arr) {
  return Object.prototype.toString.call(arr) === "[Object Array]";
}

该方法精确且优雅,因此被很多库所采纳,最终在ES5被作为isArray方法引入了Array,参照MDN。现在你不需要自定义检测方法了,直接用isArray()即可。

其他检测方法,都各有缺陷,不能100%精确。但作为一种思路是可以借鉴的。例如依赖Array是唯一包含sort方法的对象的事实来检测:

function isArray(arr) {
  return typeof arr.sort === "function";
}

如果是自定义对象也定义了sort方法,该方法就失效了。

五、属性

检测属性是否在实例对象中应该用hasOwnProperty。如果你不关心属性是在实例对象中还是在原型对象中,可以简单点用in

例如检测字面量对象属性:

var Person = {
  name: "Jack",
  age: 33
};
if("name" in Person) { … }         //true
if(Person.hasOwnProperty("name")) { … }  //true

例如实例对象属性:

var Person = function (name, age) {
  this.name = name;
  this.age = age;
};
Person.prototype.location = "Shanghai";

var me = new Person("Jack", 33)
if("name" in me) { … }         //true
if(me.hasOwnProperty("name")) { … }  //true
if("location" in me) { … }       //true
if(me.hasOwnProperty("location")) { … }//false

除此之外其他方法都不好:

if (object[propName])      //Not Good,你怎么知道属性值不是0或1?
if (object[propName] === null)    //Not Good,你怎么知道属性值不是null?
if (object[propName] === undefined)  //Not Good,你怎么知道属性值不是undefined?

总结

用typeof检测string,number,boolean,undefined,Function

用===检测null

用isArray()检测Array

用instanceof检测内置对象(除Function和Array)和自定义对象

用hasOwnProperty检测属性是否在实例对象中。如果你不关心属性是在实例对象中还是在原型对象中,可以简单点用in

好了,本篇介绍如何检测JavaScript各种类型的内容就到这里了,希望大家能够认真学习本文的内容,或许对大家学习JavaScript有所帮助。

Javascript 相关文章推荐
节点的插入之append()和appendTo()的用法介绍
Jan 13 Javascript
js图片自动轮播代码分享(js图片轮播)
May 06 Javascript
网页实时显示服务器时间和javscript自运行时钟
Jun 09 Javascript
Highcharts学习之坐标轴
Aug 02 Javascript
Move.js入门
Feb 08 Javascript
用POSTMAN发送JSON格式的POST请求示例
Sep 04 Javascript
每个 JavaScript 工程师都应懂的33个概念
Oct 22 Javascript
javascript事件监听与事件委托实例详解
Aug 16 Javascript
关于ligerui子页面关闭后,父页面刷新,重新加载的方法
Sep 27 Javascript
Vue.js数字输入框组件使用方法详解
Oct 19 Javascript
Openlayers学习之加载鹰眼控件
Sep 28 Javascript
js中Map和Set的用法及区别实例详解
Feb 15 Javascript
详解js中的apply与call的用法
Jul 30 #Javascript
javascript回到顶部特效
Jul 30 #Javascript
javascript鼠标滑过显示二级菜单特效
Nov 18 #Javascript
避免jQuery名字冲突 noConflict()方法
Jul 30 #Javascript
分享jQuery封装好的一些常用操作
Jul 28 #Javascript
一个仿微博登陆邮箱提示框js开发案例
Jul 28 #Javascript
利用JS实现数字增长
Jul 28 #Javascript
You might like
php excel类 phpExcel使用方法介绍
2010/08/21 PHP
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
php学习笔记(三)操作符与控制结构
2011/08/06 PHP
ueditor 1.2.6 使用方法说明
2013/07/24 PHP
ASP和PHP实现生成网站快捷方式并下载到桌面的方法
2014/05/08 PHP
php设计模式之简单工厂模式详解
2014/09/04 PHP
Zend Framework路由器用法实例详解
2016/12/11 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
做网页的一些技巧(续)
2007/02/01 Javascript
Flash+XML滚动新闻代码 无图片 附源码下载
2007/11/22 Javascript
用javascript获取textarea中的光标位置
2008/05/06 Javascript
浅谈javascript的原型继承
2012/07/25 Javascript
jquery文本框中的事件应用以输入邮箱为例
2014/05/06 Javascript
Javascript基础教程之数据类型转换
2015/01/18 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
2016/02/16 Javascript
全面了解JavaScript对象进阶
2016/07/19 Javascript
JavaScript实现自定义媒体播放器方法介绍
2017/01/03 Javascript
js实现导航栏中英文切换效果
2017/01/16 Javascript
es6中的解构赋值、扩展运算符和rest参数使用详解
2017/09/28 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
2019/05/16 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
Python对列表排序的方法实例分析
2015/05/16 Python
python搭建服务器实现两个Android客户端间收发消息
2018/04/12 Python
Python使用Phantomjs截屏网页的方法
2018/05/17 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
vscode+PyQt5安装详解步骤
2020/08/12 Python
static函数与普通函数有什么区别
2015/12/25 面试题
移动通信专业自荐信范文
2013/11/12 职场文书
《再见了,亲人》教学反思
2014/02/26 职场文书
网吧消防安全责任书
2014/07/29 职场文书
复兴之路观后感
2015/06/02 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
企业愿景口号
2015/12/25 职场文书
教师实习自我鉴定总结
2019/08/20 职场文书
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android