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 相关文章推荐
json 入门基础教程 推荐
Oct 31 Javascript
javascript分页代码(当前页码居中)
Sep 20 Javascript
javaScript基础语法介绍
Feb 28 Javascript
jqGrid中文文档之选项设置
Dec 02 Javascript
Javascript类型转换的规则实例解析
Feb 23 Javascript
微信小程序 免费SSL证书https、TLS版本问题的解决办法
Dec 14 Javascript
js模仿微信朋友圈计算时间显示几天/几小时/几分钟/几秒之前
Apr 27 Javascript
bootstrap modal+gridview实现弹出框效果
Aug 15 Javascript
Vue基础学习之项目整合及优化
Jun 02 Javascript
JavaScript数组去重实现方法小结
Jan 17 Javascript
javascript浅层克隆、深度克隆对比及实例解析
Feb 09 Javascript
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
Apr 24 Vue.js
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
德生BCL3000的电路分析和打磨
2021/03/02 无线电
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
PHP管理依赖(dependency)关系工具 Composer的自动加载(autoload)
2014/08/18 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
2017/03/15 PHP
JQuery与JSon实现的无刷新分页代码
2011/09/13 Javascript
为开发者准备的10款最好的jQuery日历插件
2014/02/04 Javascript
js实现下拉列表选中某个值的方法(3种方法)
2015/12/17 Javascript
最简单的JavaScript图片轮播代码(两种方法)
2015/12/18 Javascript
JQuery Mobile实现导航栏和页脚
2016/03/09 Javascript
Vue数据驱动模拟实现1
2017/01/11 Javascript
详解nodejs爬虫程序解决gbk等中文编码问题
2017/04/06 NodeJs
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
轻松解决JavaScript定时器越走越快的问题
2019/05/13 Javascript
js实现打字小游戏
2019/12/17 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
2020/02/10 Javascript
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
[30:51]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第一局
2016/03/04 DOTA
python实现人人网登录示例分享
2014/01/19 Python
python使用pandas实现数据分割实例代码
2018/01/25 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
2018/04/17 Python
完美解决python中ndarray 默认用科学计数法显示的问题
2018/07/14 Python
Python中的__init__作用是什么
2020/06/09 Python
帕克纽约:PARKER NY
2018/12/09 全球购物
Ooni英国官网:披萨烤箱
2020/05/31 全球购物
介绍一下Transact-SQL中SPACE函数的用法
2015/09/01 面试题
解释下面关于J2EE的名词
2013/11/15 面试题
英语专业毕业生自荐信
2013/10/28 职场文书
数控专业应届生求职信
2013/11/27 职场文书
大一军训感言
2014/01/09 职场文书
新学期开学寄语
2014/01/18 职场文书
家长会主持词
2014/03/26 职场文书
五心教育心得体会
2014/09/04 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
学习优秀党务工作者先进事迹材料思想报告
2014/09/17 职场文书
消防宣传语大全
2015/07/13 职场文书
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang