JS中检测数据类型的几种方式及优缺点
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
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 这两种输出的方式其实都是把要输出的内容先转换为字符串,然后再输出的
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中检测数据类型的几种方式及优缺点的更多相关文章
- 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 ...
随机推荐
- ODAC (V9.5.15) 学习笔记(二十)大数据量获取处理
ODAC获取数据的效率比较高,在Web程序中希望能够更快获取第一页的数据时,可以有几种方式: 1.在数据库中进行分页处理: 2.获取所有数据,只是快速返回第一页数据. 第一种方案对应用服务器资源消耗最 ...
- ux.form.field.Verify 验证码控件
//验证码控件 Ext.define('ux.form.field.Verify', { extend: 'Ext.container.Container', alias: ['widget.fiel ...
- 安装cvxpy遇到的问题与解决方案(ubuntu14.10,python 2.7.8)
应该说,cvxpy的安装说明是很棒的,一步一步非常清楚,www.cvxpy.org/en/latest/install/index.html 可是,我照着做完之后,还是不能import cvxpy,不 ...
- bower 新建.bowerrc文件
Twitter工程师团队推出了Bower,这是一个针对Web开发的包管理器.该工具主要用来帮助用户轻松安装CSS.JavaScript.图像等相关包,并管理这些包之间的依赖. 随着网页功能变得越来越复 ...
- Codeforces Round #197 (Div. 2) (A、B、C、D、E五题合集)
A. Helpful Maths 题目大意 给一个连加计算式,只包含数字 1.2.3,要求重新排序,使得连加的数字从小到大 做法分析 把所有的数字记录下来,从小到大排序输出即可 参考代码 #inclu ...
- Touch Event
转自: http://hi.baidu.com/masaiui/item/971775e8b316238bc10d754b 参考: http://hedgehogking.com/?p=55 ...
- 【PRML读书笔记-Chapter1-Introduction】1.1 Example:Polynomial Curve Fitting
书中给出了一个典型的曲线拟合的例子,给定一定量的x以及对应的t值,要你判断新的x对应的t值多少. 任务就是要我们去发现潜在的曲线方程:sin(2πx) 这时就需要概率论的帮忙,对于这种不确定给t赋何值 ...
- Android应用安全之外部动态加载DEX文件风险
1. 外部动态加载DEX文件风险描述 Android 系统提供了一种类加载器DexClassLoader,其可以在运行时动态加载并解释执行包含在JAR或APK文件内的DEX文件.外部动态加载DEX文件 ...
- 理解js中的自由变量以及作用域的进阶
如果你不知道什么是作用域,建议你先看什么是作用域链,什么是原型链.这篇文章,因为这些内容都是有关联性的. 什么是自由变量? 如我在全局中定义了一个变量a,然后我在函数中使用了这个a,这个a就可以称之为 ...
- umbraco之DocumentType
DocumentType定义了数据字段,这就像我们在数据库中定义表一样,这个数据字段就像表中的一个字段或者一个列.但不同的是,在umbraco里数据是分等级而不是一个表格性质. 这样就可以使用一个基本 ...