如何检测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高级学习笔记整理
Aug 14 Javascript
jQuery中trigger()方法用法实例
Jan 19 Javascript
angular ngClick阻止冒泡使用默认行为的方法
Nov 03 Javascript
Bootstrap Search Suggest使用例子
Dec 21 Javascript
js仿小米手机上下滑动效果
Feb 05 Javascript
详解jQuery同步Ajax带来的UI线程阻塞问题及解决办法
Aug 09 jQuery
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
Nov 14 Javascript
Angular 如何使用第三方库的方法
Apr 18 Javascript
Vue异步组件处理路由组件加载状态的解决方案
Sep 07 Javascript
vue2.0实现的tab标签切换效果(内容可自定义)示例
Feb 11 Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 Javascript
JavaScript对象字面量和构造函数原理与用法详解
Apr 18 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控制linux服务器常用功能 关机 重启 开新站点等
2012/09/05 PHP
PHP基于mssql扩展远程连接MSSQL的简单实现方法
2016/10/08 PHP
php+ajax实现商品对比功能示例
2019/04/13 PHP
IE中jscript/javascript的条件编译
2006/09/07 Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
2012/08/14 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
jquery重复提交请求的原因浅析
2014/05/23 Javascript
浅析javascript中function 的 length 属性
2014/05/27 Javascript
jquery实现加载进度条提示效果
2015/11/23 Javascript
关于不同页面之间实现参数传递的几种方式讨论
2017/02/13 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
js仿淘宝商品放大预览功能
2017/03/15 Javascript
jQuery实现简单漂亮的Nav导航菜单效果
2017/03/29 jQuery
layui导航栏实现代码
2017/05/19 Javascript
jquery加载单文件vue组件的方法
2017/06/20 jQuery
Vue单文件组件基础模板小结
2017/08/10 Javascript
mongoose设置unique不生效问题的解决及如何移除unique的限制
2017/11/07 Javascript
了解javascript中的Dom操作
2019/05/27 Javascript
请求时token过期自动刷新token操作
2020/09/11 Javascript
Vue中nprogress页面加载进度条的方法实现
2020/11/13 Javascript
[02:15]你好,这就是DOTA!
2015/08/05 DOTA
详解C++编程中一元运算符的重载
2016/01/19 Python
python中requests库session对象的妙用详解
2017/10/30 Python
使用apidocJs快速生成在线文档的实例讲解
2018/02/07 Python
python使用筛选法计算小于给定数字的所有素数
2018/03/19 Python
Python2.7 实现引入自己写的类方法
2018/04/29 Python
解决python字典对值(值为列表)赋值出现重复的问题
2019/01/20 Python
大学生就业自荐信
2013/10/26 职场文书
棉花姑娘教学反思
2014/02/15 职场文书
给领导的检讨书
2014/02/16 职场文书
医学专业应届生的自我评价
2014/02/28 职场文书
乡镇信息公开实施方案
2014/03/23 职场文书
二年级小学生评语
2014/04/21 职场文书
市场开发计划书
2014/05/07 职场文书
体操比赛口号
2014/06/10 职场文书
2014年安全生产责任书
2014/07/22 职场文书