如何检测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实现验证IP地址等相关信息代码
May 10 Javascript
JavaScript文本框脚本编写的注意事项
Jan 25 Javascript
AngularJS  自定义指令详解及实例代码
Sep 14 Javascript
AngularJS中$http使用的简单介绍
Mar 17 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
Nov 15 Javascript
基于vue-cli创建的项目的目录结构及说明介绍
Nov 23 Javascript
集成vue到jquery/bootstrap项目的方法
Feb 10 jQuery
如何更好的编写js async函数
May 13 Javascript
JS中通过url动态获取图片大小的方法小结(两种方法)
Oct 31 Javascript
解决vue跨域axios异步通信问题
Apr 17 Javascript
RxJS的入门指引和初步应用
Jun 15 Javascript
React服务端渲染原理解析与实践
Mar 04 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数组的交集array_intersect(),array_intersect_assoc(),array_inter_key()函数的小问题
2011/05/29 PHP
PHP的邮件群发系统phplist配置方法详细总结
2016/03/30 PHP
laravel5创建service provider和facade的方法详解
2016/07/26 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
用js判断浏览器是否是IE的比较好的办法
2007/05/08 Javascript
将CKfinder整合进CKEditor3.0的新方法
2010/01/10 Javascript
图片无缝滚动代码(向左/向下/向上)
2013/04/10 Javascript
Javascript中设置默认参数值示例
2014/09/11 Javascript
jQuery实现菜单式图片滑动切换
2015/03/14 Javascript
Webpack 实现 Node.js 代码热替换
2015/10/22 Javascript
javascript倒计时效果实现
2015/11/12 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
2016/08/19 Javascript
angular学习之ngRoute路由机制
2017/04/12 Javascript
angularjs利用directive实现移动端自定义软键盘的示例
2017/09/20 Javascript
vue.js实现只弹一次弹框
2018/01/29 Javascript
对angular4子路由&辅助路由详解
2018/10/09 Javascript
vue动态注册组件实例代码详解
2019/05/30 Javascript
基于Vue 撸一个指令实现拖拽功能
2019/10/09 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
2020/06/02 jQuery
[51:15]2014 DOTA2国际邀请赛中国区预选赛 Orenda VS LGD-GAMING
2014/05/22 DOTA
解析Python中的异常处理
2015/04/28 Python
快速排序的算法思想及Python版快速排序的实现示例
2016/07/02 Python
利用python打印出菱形、三角形以及矩形的方法实例
2017/08/08 Python
python jieba分词并统计词频后输出结果到Excel和txt文档方法
2018/02/11 Python
Python打开文件,将list、numpy数组内容写入txt文件中的方法
2018/10/26 Python
Python 最强编辑器详细使用指南(PyCharm )
2019/09/16 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
Python tkinter制作单机五子棋游戏
2020/09/14 Python
Python 的 f-string 可以连接字符串与数字的原因解析
2021/02/20 Python
爱尔兰橄榄球店:Irish Rugby Store
2019/12/05 全球购物
标准毕业生自荐信范文
2013/11/04 职场文书
特教教师先进事迹
2014/05/21 职场文书
西部计划志愿者工作总结
2015/08/11 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
python 机器学习的标准化、归一化、正则化、离散化和白化
2021/04/16 Python
Python使用openpyxl批量处理数据
2021/06/23 Python