JS中检测数据类型的几种方式及优缺点小结


Posted in Javascript onDecember 12, 2016

1、typeof 用来检测数据类型的运算符

typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"、"string"、"boolean"、"undefined"、"object"、"function"

局限性:

1)typeof null ->"object"

2)检测的不管是数组还是正则都返回的是"object",所以typeof不能判断一个值是否为数组

console.log(typeof [12, 23]);//->"Object"

2、instanceof/constructor

检测某一个实例是否属于某一个类

使用instanceof/constructor可以检测数组和正则

console.log([] instanceof Array);//->true
console.log(/^$/ instanceof RegExp);//->true
console.log([] instanceof Object);//->true
console.log([].constructor === Array);//->true
console.log([].constructor === Object);//->false
constructor可以避免instanceof检测数组的时候,用Object也是true的问题
console.log({}.constructor === Object);//true<br>console.log([].constructor === Object);//false

局限性:

1)用instanceof检测的时候,只要当前的这个类在实例的原型链上(可以通过原型链__proto__找到它),检测出来的结果都是true

var oDiv = document.getElementById("div1");
//HTMLDivElement->HTMLElement->Element->Node->EventTarget->Object
console.log(oDiv instanceof HTMLDivElement);//->true
console.log(oDiv instanceof Node);//->true
console.log(oDiv instanceof Object);//->true

2)基本数据类型的值是不能用instanceof来检测的

console.log(1 instanceof Number);//->false

数组创建的两种方式(对象、正则、函数...)

对于引用数据类型来说,我们两种方式创建出来的都是所属类的实例,而且都是对象数据类型的值,是没有区别的

var ary = [];
var ary = new Array;

对于基本数据类型来说,虽然不管哪一种方式创建出来的都是所属类的一个实例(在类的原型上定义的方法都可以使用),但是字面量方式创建出来的是基本数据类型,而实例方式创建出来的是对象数据类型

var num1 = 1;
var num2 = new Number("1");
console.log(typeof num1,typeof num2);//->"number" "object" 

 3)在类的原型继承中,instanceof检测出来的结果其实是不准确的

function Fn() {}
var f = new Fn;
console.log(f instanceof Array);//->false f不是一个数组,它就是一个普通的实例(普通的对象)

虽然Fn继承了Array,但是f没有length和数字索引哪些东西,所以f应该不是数组才对,但是用instanceof检测的结果却是true,因为f虽然不是数组,但是在f的原型链上可以找到Array

function Fn() {
}
Fn.prototype = new Array;//->Fn子类继承了Array这个父类中的属性和方法
var f = new Fn;
console.log(f instanceof Array);//->true

3、Object.prototype.toString.call(value) ->找到Object原型上的toString方法,让方法执行,并且让方法中的this变为value(value->就是我们要检测数据类型的值)

Object.prototype.toString常用来判断对象值属于哪种内置属性,它返回一个JSON字符串——"[object 数据类型]"。

由于许多引用类型都重写了Object继承来的的toStrong方法,所以我们通常使用call或者apply借用Object.prototype.toString函数来判断数据类型。

当然,这样调用的默认前提是Object.prototype.toString没有被重写。

toString:一个方法,转换为字符串数据类型用的方法

每一个数据类型所属类的原型上都有toString方法,例如:Number.prototype/String.prototype/Array.prototype/Function.prototype...

除了Object上的toString,其他类原型上的toString都是把当前的数据值转换为字符串的意思

null和undefined比较的特殊:他们所属类Null/Undefined的原型上也有toString,只不过不让我们用而已,不仅如此其实类的原型都给屏蔽了

HTML元素对象的toString:虽然它的原型链很长,但是在其它类的原型上都没有toString,只有在最底层Object.prototype这上才有

var oDiv = document.getElementById("div1");
oDiv.toString(); //->调用的其实也是Object.prototype.toString...
//alert、document.write 这两种输出的方式其实都是把要输出的内容先转换为字符串,然后再输出的<br>
alert([]); //->""
alert(true); //->"true"
alert({}); //->这个就要调用Object.prototype上的toString了 ->"[object Object]"
//定义toString变量是为了简便书写,同时降低作用域链检索的性能损耗
var toString = Object.prototype.toString;
console.log(toString.call(1));//[object Number]
console.log(toString.call(undefined));//[object Undefined]
console.log(toString.call(null));//[object Null]
console.log(toString.call(false));//[object Boolean]
console.log(toString.call("s"));//[object String]
console.log(toString.call({}));//[object Object]
console.log(toString.call(/[a]/g));//[object RegExp]
console.log(toString.call(function(){}));//[object Function]

is系列函数的简易实现

在明白数据类型怎么检测后,下面我们来简单实现is系列检测函数。

var dataType = {
    '[object Null]' : 'null',
    '[object Undefined]' : 'undefiend',
    '[object Boolean]' : 'boolean',
    '[object Number]' : 'number',
    '[object String]' : 'string',
    '[object Function]' : 'function',
    '[object Array]' : 'array',
    '[object Date]' : 'date',
    '[object RegExp]' : 'regexp',
    '[object Object]' : 'object',
    '[object Error]' : 'error'
  },
  toString = Object.prototype.toString;
function type(obj) {
  return dataType[toString.call(obj)];
}
//生成is系列函数
function createValidType() {
  for(var p in dataType) {
    var objType = p.slice(8, -1);
    (function(objType) {
      window['is' + objType] = function(obj) {
        return type(obj) === objType.toLowerCase();
      }
    })(objType)
  }
}
createValidType();
console.log(isObject({}));//true
console.log(isDate(new Date()));//true
console.log(isBoolean(false));//true
console.log(isString(1));//false
console.log(isError(1));//false
console.log(isError(new Error()));//true
console.log(isArray([]));//true
console.log(isArray(1));//false

上面代码里分别实现了isNull、isUndefined、isBoolean、isNumber、isString、isFunction、isArray、isDate、isRegExp、isObject、isError这11个检测函数。同时也实现了type函数,用以检测数据类型。

console.log(type({}));//"object"
console.log(type(new Date()));//"date"
console.log(type(false));//"boolean"
console.log(type(1));//"number"
console.log(type(1));//"number"
console.log(type(new Error()));//"error"
console.log(type([]));//"array"
console.log(type(1));//"number"

createValidType函数巧用闭包保存数据状态的特性,批量生成is系列函数。

以上所述是小编给大家介绍的JS中检测数据类型的几种方式及优缺点小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript复制对象使用说明
Jun 28 Javascript
JS常见问题整理(持续更新)
Aug 06 Javascript
js实现文件上传表单域美化特效
Nov 02 Javascript
jquery ztree异步搜索(搜叶子)实践
Feb 25 Javascript
javascript小数精度丢失的完美解决方法
May 31 Javascript
jQuery File Upload文件上传插件使用详解
Dec 06 Javascript
使用vue实现简单键盘的示例(支持移动端和pc端)
Dec 25 Javascript
vue 实现全选全不选的示例代码
Mar 29 Javascript
Vue微信项目按需授权登录策略实践思路详解
May 07 Javascript
微信小程序全局变量功能与用法详解
Jan 22 Javascript
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
Sep 09 Javascript
vuecli项目构建SSR服务端渲染的实现
Oct 30 Javascript
JS仿京东移动端手指拨动切换轮播图效果
Apr 10 #Javascript
JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
Dec 12 #Javascript
JavaScript利用正则表达式替换字符串中的内容
Dec 12 #Javascript
基于BootstrapValidator的Form表单验证(24)
Dec 12 #Javascript
Sequelize中用group by进行分组聚合查询
Dec 12 #Javascript
js原生之焦点图转换加定时器实例
Dec 12 #Javascript
IntersectionObserver API 详解篇
Dec 11 #Javascript
You might like
随机广告显示(PHP函数)
2006/10/09 PHP
php中关于普通表单多文件上传的处理方法
2011/03/25 PHP
PHP中的正则表达式函数介绍
2012/02/27 PHP
PHP内核学习教程之php opcode内核实现
2016/01/27 PHP
微信第三方登录(原生)demo【必看篇】
2017/05/26 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
jQuery 1.5 源码解读 面向中高阶JSER
2011/04/05 Javascript
初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能
2011/12/26 Javascript
js操作iframe父子窗体示例
2014/05/22 Javascript
浅析AngularJS中的生命周期和延迟处理
2015/06/18 Javascript
JS实现仿苹果底部任务栏菜单效果代码
2015/08/28 Javascript
理解js回收机制通俗易懂版
2016/02/29 Javascript
JS去掉字符串前后空格或去掉所有空格的用法
2017/03/25 Javascript
使用AngularJS编写多选按钮选中时触发指定方法的指令代码详解
2017/07/24 Javascript
JavaScript中附件预览功能实现详解(推荐)
2017/08/15 Javascript
JS实现将链接生成二维码并转为图片的方法
2018/03/17 Javascript
echarts设置图例颜色和地图底色的方法实例
2018/08/01 Javascript
[01:11:15]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[00:56]跨越时空加入战场 全新祈求者身心“失落奇艺侍祭”展示
2019/07/20 DOTA
Python的mysql数据库的更新如何实现
2017/07/31 Python
Python对列表中的各项进行关联详解
2017/08/15 Python
python通过ffmgep从视频中抽帧的方法
2018/12/05 Python
python 动态生成变量名以及动态获取变量的变量名方法
2019/01/20 Python
Python实现的IP端口扫描工具类示例
2019/02/15 Python
Python合并同一个文件夹下所有PDF文件的方法
2019/03/11 Python
创建Django项目图文实例详解
2019/06/06 Python
利用python-pypcap抓取带VLAN标签的数据包方法
2019/07/23 Python
Python中pyecharts安装及安装失败的解决方法
2020/02/18 Python
基于Python实现天天酷跑功能
2021/01/06 Python
社区巾帼文明岗事迹材料
2014/06/03 职场文书
公共场所禁烟倡议书
2014/08/30 职场文书
法定代表人授权委托书范本
2014/10/07 职场文书
大国崛起英国观后感
2015/06/02 职场文书
2019年大学推荐信
2019/06/24 职场文书
golang生成并解析JSON
2022/04/14 Golang