如何检测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 相关文章推荐
cloudgamer出品ImageZoom 图片放大效果
Apr 01 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
Feb 16 Javascript
Extjs4 消息框去掉关闭按钮(类似Ext.Msg.alert)
Apr 02 Javascript
利用js(jquery)操作Cookie的方法说明
Dec 19 Javascript
JavaScript中的函数的两种定义方式和函数变量赋值
May 12 Javascript
node.js中的fs.readFile方法使用说明
Dec 15 Javascript
分析javascript中9 个常见错误阻碍你进步
Sep 18 Javascript
ionic3+Angular4实现接口请求及本地json文件读取示例
Oct 11 Javascript
深入浅析ES6 Class 中的 super 关键字
Oct 20 Javascript
基于vue中css预加载使用sass的配置方式详解
Mar 13 Javascript
js使用Promise实现简单的Ajax缓存
Nov 14 Javascript
详解可以用在VS Code中的正则表达式小技巧
May 14 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 文件夹删除、php清除缓存程序
2009/08/25 PHP
PHP 图片文件上传实现代码
2010/12/29 PHP
深入解析PHP垃圾回收机制对内存泄露的处理
2013/06/14 PHP
php多个文件及图片上传实例详解
2014/11/10 PHP
php编程每天必学之表单验证
2016/03/01 PHP
PHP实现的微信公众号扫码模拟登录功能示例
2019/05/30 PHP
js 自定义的联动下拉框
2010/02/07 Javascript
Extjs4 类的定义和扩展实例
2013/06/28 Javascript
不同编码的页面表单数据乱码问题解决方法
2015/02/15 Javascript
Bootstrap3 多选和单选框(checkbox)
2016/12/29 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
2017/12/16 Javascript
js实现搜索栏效果
2018/11/16 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
函数式编程入门实践(一)
2019/04/20 Javascript
js常见遍历操作小结
2019/06/06 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
vue监听dom大小改变案例
2020/07/29 Javascript
vue中使用腾讯云Im的示例
2020/10/23 Javascript
[00:21]DOTA2亚洲邀请赛 Logo演绎
2015/02/07 DOTA
python更新列表的方法
2015/07/28 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
Pandas GroupBy对象 索引与迭代方法
2018/11/16 Python
Python 隐藏输入密码时屏幕回显的实例
2019/02/19 Python
TFRecord格式存储数据与队列读取实例
2020/01/21 Python
python 爬取疫情数据的源码
2020/02/09 Python
python多项式拟合之np.polyfit 和 np.polyld详解
2020/02/18 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
2020/03/09 Python
查看keras的默认backend实现方式
2020/06/19 Python
Python DES加密实现原理及实例解析
2020/07/17 Python
Parfumdreams芬兰:购买香水和化妆品
2021/02/13 全球购物
英国最大的天然和有机产品在线零售商之一:Big Green Smile
2020/05/06 全球购物
学术会议邀请函范文
2014/01/22 职场文书
2015年小学英语教师工作总结
2015/05/12 职场文书
在职证明书模板
2015/06/15 职场文书
导游词之五台山
2019/10/11 职场文书
基于CSS3画一个iPhone
2021/04/21 HTML / CSS