如何检测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 相关文章推荐
javascipt匹配单行和多行注释的正则表达式
Nov 20 Javascript
通过复制Table生成word和excel的javascript代码
Jan 20 Javascript
node.js中的fs.realpathSync方法使用说明
Dec 16 Javascript
Angularjs制作简单的路由功能demo
Apr 14 Javascript
基于js实现投票的实例代码
Aug 04 Javascript
jquery实现二级导航下拉菜单效果
Dec 18 Javascript
javascript设计模式之module(模块)模式
Aug 19 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
Sep 12 Javascript
Bootstrap和Java分页实例第二篇
Dec 23 Javascript
js遮罩效果制作弹出注册界面效果
Jan 25 Javascript
关于不同页面之间实现参数传递的几种方式讨论
Feb 13 Javascript
js中Number数字数值运算后值不对的解决方法
Feb 28 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
set_include_path在win和linux下的区别
2008/01/10 PHP
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
php排序算法(冒泡排序,快速排序)
2012/10/09 PHP
分享最受欢迎的5款PHP框架
2014/11/27 PHP
PHP 实现代码复用的一个方法 traits新特性
2015/02/22 PHP
利用Fix Rss Feeds插件修复WordPress的Feed显示错误
2015/12/19 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
获取任意Html元素与body之间的偏移距离 offsetTop、offsetLeft (For:IE5+ FF1 )[
2006/12/22 Javascript
用户注册常用javascript代码
2009/08/29 Javascript
关于js类的定义
2011/06/28 Javascript
javascript日期格式化方法汇总
2015/10/04 Javascript
javascript生成img标签的3种实现方法(对象、方法、html)
2015/12/25 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
2016/05/19 Javascript
全面解析Bootstrap中tab(选项卡)的使用方法
2016/06/06 Javascript
jQuery实现的tab标签切换效果示例
2016/09/05 Javascript
Vue入门之数据绑定(小结)
2018/01/08 Javascript
100行代码实现一个vue分页组功能
2018/11/06 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
python client使用http post 到server端的代码
2013/02/10 Python
python使用paramiko实现远程拷贝文件的方法
2016/04/18 Python
浅谈django中的认证与登录
2016/10/31 Python
python 读写文件,按行修改文件的方法
2018/07/12 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
Python Gitlab Api 使用方法
2019/08/28 Python
HTML5 Notification(桌面提醒)功能使用实例
2014/03/17 HTML / CSS
HTML5 source标签:媒介元素定义媒介资源
2018/01/29 HTML / CSS
三陽商会官方网站:Sanyo iStore
2019/05/15 全球购物
歌唱比赛策划方案
2014/06/06 职场文书
鉴史问廉观后感
2015/06/10 职场文书
出纳2015年度工作总结范文
2015/10/14 职场文书
选调生挂职锻炼工作总结
2015/10/23 职场文书
网络研修心得体会
2016/01/08 职场文书
导游词之铁岭象牙山
2019/12/06 职场文书
Python实现简繁体转换
2021/06/07 Python
浅谈PostgreSQL表分区的三种方式
2021/06/29 PostgreSQL
微软团队与 NASA 科学家和惠普企业(HPE)的工程师合作
2022/04/21 数码科技