如何检测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 Excel操作知识点
Apr 24 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
Oct 11 Javascript
js切换光标示例代码
Oct 10 Javascript
基于JS实现textarea中获取动态剩余字数的方法
May 25 Javascript
js中window.open的参数及注意注意事项
Jul 06 Javascript
jQuery UI插件实现百度提词器效果
Nov 21 Javascript
Bootstrap BootstrapDialog使用详解
Feb 17 Javascript
javascript实现QQ空间相册展示源码
Dec 12 Javascript
Javascript的this详解
Mar 23 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
Jun 18 Javascript
vue中实现点击空白区域关闭弹窗的两种方法
Dec 30 Vue.js
原生JavaScript实现购物车
Jan 10 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 字符串操作入门教程
2006/12/06 PHP
PHP面向对象学习笔记之二 生成对象的设计模式
2012/10/06 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
php微信公众号开发之校园图书馆
2018/10/20 PHP
PHP面向对象程序设计中的self、static、parent关键字用法分析
2019/08/14 PHP
Jquery 获取表单text,areatext,radio,checkbox,select值的代码
2009/11/12 Javascript
Jquery工作常用实例 使用AJAX使网页进行异步更新
2011/07/26 Javascript
javascript高级学习笔记整理
2011/08/14 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
使用jQuery的attr方法来修改onclick值
2014/07/07 Javascript
jquery动画效果学习笔记(8种效果)
2015/11/13 Javascript
jquery对象访问是什么及使用方法介绍
2016/05/03 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
jquery select2的使用心得(推荐)
2016/12/04 Javascript
JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题
2016/12/23 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
JS中创建自定义类型的常用模式总结【工厂模式,构造函数模式,原型模式,动态原型模式等】
2019/01/19 Javascript
JS实现电话号码的字母组合算法示例
2019/02/26 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
2019/05/27 Javascript
Vue.js实现tab切换效果
2019/07/24 Javascript
原生JavaScript创建不可变对象的方法简单示例
2020/05/07 Javascript
vue render函数动态加载img的src路径操作
2020/10/26 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
python中如何使用朴素贝叶斯算法
2017/04/06 Python
python matplotlib绘图,修改坐标轴刻度为文字的实例
2018/05/25 Python
Django中的FBV和CBV用法详解
2019/09/15 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
python Protobuf定义消息类型知识点讲解
2021/03/02 Python
input元素的url类型和email类型简介
2012/07/11 HTML / CSS
图片上传插件ImgUploadJS:用HTML5 File API 实现截图粘贴上传、拖拽上传
2016/01/20 HTML / CSS
岗位职责的含义
2013/11/17 职场文书
人力资源经理自我评价
2014/01/04 职场文书
小学教师教学随笔
2015/08/14 职场文书
预备党员表决心的话
2015/09/22 职场文书
JavaScript数组 几个常用方法总结
2021/11/11 Javascript
基于Python实现对比Exce的工具
2022/04/07 Python