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 = ElementById("div1");
js原型和原型链的理解//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、String.call(value) ->到Object原型上的toString⽅法,让⽅法执⾏,并且让⽅法中的this变为value(value->就是我们要检测数据类型的值)
String常⽤来判断对象值属于哪种内置属性,它返回⼀个JSON字符串——"[object 数据类型]"。
由于许多引⽤类型都重写了Object继承来的的toStrong⽅法,所以我们通常使⽤call或者apply借⽤String函数来判断数据类型。
当然,这样调⽤的默认前提是String没有被重写。
toString:⼀个⽅法,转换为字符串数据类型⽤的⽅法
每⼀个数据类型所属类的原型上都有toString⽅法,例如:Number.prototype/String.prototype/Array.prototype/
除了Object上的toString,其他类原型上的toString都是把当前的数据值转换为字符串的意思
null和undefined⽐较的特殊:他们所属类Null/Undefined的原型上也有toString,只不过不让我们⽤⽽已,不仅如此其实类的原型都给屏蔽了HTML元素对象的toString:虽然它的原型链很长,但是在其它类的原型上都没有toString,只有在最底层Object.prototype这上才有
var oDiv = ElementById("div1");
//alert、document.write 这两种输出的⽅式其实都是把要输出的内容先转换为字符串,然后再输出的
alert([]); //->""
alert(true); //->"true"
alert({}); //->这个就要调⽤Object.prototype上的toString了 ->"[object Object]"
//定义toString变量是为了简便书写,同时降低作⽤域链检索的性能损耗
var toString = String;
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 = String;
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) === LowerCase();
}
})(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系列函数。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论