如何检测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 相关文章推荐
javascript编程起步(第五课)
Feb 27 Javascript
jQuery让控件左右移动的三种实现方法
Sep 08 Javascript
jquery通过visible来判断标签是否显示或隐藏
May 08 Javascript
JavaScript模拟数组合并concat
Mar 06 Javascript
jQuery选择器基础入门教程
May 10 Javascript
Javascript基础_简单比较undefined和null 值
Jun 14 Javascript
基于JavaScript实现点击页面任何位置返回
Aug 31 Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 Javascript
基于rem的移动端响应式适配方案(详解)
Jul 07 Javascript
vue.js中created方法作用
Mar 30 Javascript
node删除、复制文件或文件夹示例代码
Aug 13 Javascript
JS函数参数的传递与同名参数实例分析
Mar 16 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 url地址栏传中文乱码解决方法集合
2010/06/25 PHP
浅析PHP递归函数返回值使用方法
2013/02/18 PHP
php自定义apk安装包实例
2014/10/20 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
完美解决thinkphp唯一索引重复时出错的问题
2017/03/31 PHP
php实现socket推送技术的示例
2017/12/20 PHP
PHP安全之register_globals的on和off的区别
2020/07/23 PHP
MacOS下PHP7.1升级到PHP7.4.15的方法
2021/02/22 PHP
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
javascript中的缓动效果实现程序
2012/12/29 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
2014/05/14 Javascript
javascript自定义的addClass()方法
2014/05/28 Javascript
JS实现当前页居中分页效果的方法
2015/06/18 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
深入理解javascript的getTime()方法
2017/02/16 Javascript
深入浅析AngularJS中的一次性数据绑定 (bindonce)
2017/05/11 Javascript
微信小程序canvas写字板效果及实例
2017/06/15 Javascript
快速搭建React的环境步骤详解
2017/11/06 Javascript
详解vue-meta如何让你更优雅的管理头部标签
2018/01/18 Javascript
jQuery使用each遍历循环的方法
2018/09/19 jQuery
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
[03:30]完美盛典趣味短片 CSGO2019年度名场面
2019/12/07 DOTA
编写Python脚本来实现最简单的FTP下载的教程
2015/05/04 Python
带你了解python装饰器
2017/06/15 Python
Python循环中else,break和continue的用法实例详解
2019/07/11 Python
Python日期格式和字符串格式相互转换的方法
2020/02/18 Python
keras多显卡训练方式
2020/06/10 Python
美国高端牛仔品牌:Silver Jeans
2019/12/12 全球购物
电子商务求职信
2014/06/15 职场文书
土地租赁意向书
2014/07/30 职场文书
辞职信的写法
2015/02/27 职场文书
环卫工作个人总结
2015/03/04 职场文书
详解Java实践之适配器模式
2021/06/18 Java/Android