JS中检测数据类型的几种方式及优缺点【转】
1、typeof 用来检测数据类型的运算符
typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"、"string"、"boolean"、"undefined"、"object"、"function"
局限性:
1)typeof null ->"object"
2)检测的不管是数组还是正则都返回的是"object",所以typeof不能判断一个值是否为数组
1
|
console.log( typeof [12, 23]); //->"Object" |
2、instanceof/constructor
检测某一个实例是否属于某一个类
使用instanceof/constructor可以检测数组和正则
1
2
3
4
5
6
|
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的问题
1
|
console.log({}.constructor === Object); //true<br>console.log([].constructor === Object);//false |
局限性:
1)用instanceof检测的时候,只要当前的这个类在实例的原型链上(可以通过原型链__proto__找到它),检测出来的结果都是true
1
2
3
4
5
|
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来检测的
1
|
console.log(1 instanceof Number); //->false |
数组创建的两种方式(对象、正则、函数...)
对于引用数据类型来说,我们两种方式创建出来的都是所属类的实例,而且都是对象数据类型的值,是没有区别的
1
2
|
var ary = []; var ary = new Array; |
对于基本数据类型来说,虽然不管哪一种方式创建出来的都是所属类的一个实例(在类的原型上定义的方法都可以使用),但是字面量方式创建出来的是基本数据类型,而实例方式创建出来的是对象数据类型
1
2
3
|
var num1 = 1; var num2 = new Number( "1" ); console.log( typeof num1, typeof num2); //->"number" "object" |
3)在类的原型继承中,instanceof检测出来的结果其实是不准确的
1
2
3
|
function Fn() {} var f = new Fn; console.log(f instanceof Array); //->false f不是一个数组,它就是一个普通的实例(普通的对象) |
虽然Fn继承了Array,但是f没有length和数字索引哪些东西,所以f应该不是数组才对,但是用instanceof检测的结果却是true,因为f虽然不是数组,但是在f的原型链上可以找到Array
1
2
3
4
5
|
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这上才有
1
2
3
4
5
6
7
|
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系列函数。
转载自:http://www.cnblogs.com/allenlei/p/6161022.html
JS中检测数据类型的几种方式及优缺点【转】的更多相关文章
- JS中检测数据类型的几种方式及优缺点
1.typeof 用来检测数据类型的运算符 typeof value 返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."string&quo ...
- JS中检测数据类型的四种方式及每个方式的优缺点
//1.typeof 用来检测数据类型的运算符 //->typeof value //->返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number". ...
- js中检测数据类型的几种方式
1.typeof 一元运算符,用来检测数据类型.只可以检测number,string,boolean,object,function,undefined. 对于基本数据类型是没有问题的,但是遇到引用数 ...
- JS中检测数据类型的四种方法
1.typeof 用来检测数据类型的运算符->typeof value->返回值首先是一个字符串,其次里面包含了对应的数据类型,例如:"number"."st ...
- 在javaScript中检测数据类型的几种方式
类型检测的方法 typeof instanceof Object.protype.toString constructor duck type:鸭子类型 typeof 返回一个字符串,适合函数对象和基 ...
- js中判断数据类型的四种方法总结
js中判断数据类型的四种方法 前言 在js中,我们经常需要判断数据的类型,那么哪些方法可以用来判断数据的类型呢?哪种方法判断数据类型最准确呢? 我们来一个个分析: 1.typeof typeof是一个 ...
- JavaScript学习12 JS中定义对象的几种方式
JavaScript学习12 JS中定义对象的几种方式 JavaScript中没有类的概念,只有对象. 在JavaScript中定义对象可以采用以下几种方式: 1.基于已有对象扩充其属性和方法 2.工 ...
- JavaScript学习12 JS中定义对象的几种方式【转】
avaScript学习12 JS中定义对象的几种方式 转自: http://www.cnblogs.com/mengdd/p/3697255.html JavaScript中没有类的概念,只有对象. ...
- JS中事件绑定的三种方式
以下是搜集的在JS中事件绑定的三种方式. 1. HTML onclick attribute <button type="button" id="upl ...
随机推荐
- 关于SimpleAdapter和ListView结合使用,实现列表视图的笔记
使用ListView需要为其添加适配器: 适配器有两种:1.ArrayAdapter --用于单独文字显示 2.SimpleAdapter --用于文字和图片显示 这里主要记录SimpleAdapt ...
- gnu coreutils-8.25 for win32 static - Beta
gnu.win32-coreutils-8.25.7z 2.7 Mb bc-1.06.tar.gz coreutils-8.25.tar.xz diffutils-3.5.tar.xz gawk-4. ...
- linux 环境变量
电脑中必不可少的就是操作系统.而Linux的发展非常迅速,有赶超微软的趋势.这里介绍Linux的知识,让你学好应用Linux系统.比如要把/etc/apache/bin目录添加到PATH中,方法有三: ...
- Android安全相关文章[不定期更新…]
http://drops.wooyun.org/papers/2893 Intent scheme URL attack http://drops.wooyun.org/tips/3812 Andro ...
- mui项目中如何使用原生JavaScript代替jquery来操作dom 转自【B5教程网】:http://www.bcty365.com/content-146-3661-1.html
最近在用mui写页面,当然了在移动App里引入jq或zepto这些框架,肯定是极不理性的.原生JS挺简单,为何需要jq?jq的成功当时是因为ie6.7.8.9.10.chrome.ff这些浏览器不兼容 ...
- css经典布局——头尾固定高度中间高度自适应布局
转载:穆乙 http://www.cnblogs.com/pigtail/ 相信做过后台管理界面的同学,都非常清楚这个布局.最直观的方式是框架这个我不想多写费话,因为我们的重心不在这里.如果有不了解的 ...
- (转)Redis使用场景及使用经验
Redis is an open source (BSD licensed), in-memory data structure store! 刚刚结束一个游戏类的活动项目,由于预估的参与人数较多,产 ...
- 第六课 touch事件
1.移动端页面在PC上浏览时,限制宽度的方法: 2.移动端页面切换设备时自动刷新页面的方法: 3.touch事件 touchstart:当手指触摸屏幕时触发.通过addEventListener添加移 ...
- 两个单选按钮(一个是,一个否 ),一个div层,实现点击隐藏,显示div
<script type="text/javascript"> function diva(){ document.getElementById('div1').sty ...
- Ajax:一种网页开发技术(Asynchronous Javascript + XML)
创建新的 XMLHttpRequest 对象(Ajax 应用程序的核心): <script language="javascript" type="text/jav ...