如何检测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 相关文章推荐
短信提示使用 特效
Jan 19 Javascript
一个网马的tips实现分析
Nov 28 Javascript
jQuery 在光标定位的地方插入文字的插件
May 10 Javascript
iframe实用操作锦集
Apr 22 Javascript
javascript 操作符(~、&、|、^、)使用案例
Dec 31 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
Jul 01 Javascript
原生js实现新闻列表展开/收起全文功能
Jan 20 Javascript
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
Mar 21 Javascript
js实现抽奖效果
Mar 27 Javascript
使用Angular CLI生成 Angular 5项目教程详解
Mar 18 Javascript
浅谈Vue3.0新版API之composition-api入坑指南
Apr 30 Javascript
JavaScript实现鼠标经过表格某行时此行变色
Nov 20 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
如何限制访问者的ip(PHPBB的代码)
2006/10/09 PHP
php5.2以下版本无json_decode函数的解决方法
2014/05/25 PHP
PHP中preg_match正则匹配中的/u、/i、/s含义
2015/04/17 PHP
PHP查看当前变量类型的方法
2015/07/31 PHP
php中青蛙跳台阶的问题解决方法
2018/10/14 PHP
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
用js实现的仿sohu博客更换页面风格(简单版)
2007/03/22 Javascript
jQuery学习笔记之Helloworld
2010/12/22 Javascript
js 判断上传文件大小及格式代码
2013/11/13 Javascript
javascript操作html控件实例(javascript添加html)
2013/12/02 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
javascript学习笔记整理(概述、变量、数据类型简介)
2015/10/25 Javascript
jQuery使用cookie与json简单实现购物车功能
2016/04/15 Javascript
详解堆的javascript实现方法
2016/11/29 Javascript
JavaScript之map reduce_动力节点Java学院整理
2017/06/29 Javascript
无限循环轮播图之运动框架(原生JS实现)
2017/10/01 Javascript
webstorm和.vue中es6语法报错的解决方法
2018/05/08 Javascript
利用vue-i18n实现多语言切换效果的方法
2019/06/19 Javascript
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例
2018/03/15 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
django之静态文件 django 2.0 在网页中显示图片的例子
2019/07/28 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
捷克多品牌在线时尚商店:ANSWEAR.cz
2020/10/03 全球购物
JPA的特点
2014/10/25 面试题
应届生个人求职信模板
2013/11/26 职场文书
创业资金计划书
2014/02/06 职场文书
电子信息工程专业求职信
2014/06/28 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
教师工作表现自我评价
2015/03/05 职场文书
2015年汽车销售工作总结
2015/04/07 职场文书
2015年小学教师培训工作总结
2015/07/21 职场文书
爱护公物主题班会
2015/08/17 职场文书