前端全栈工程化开发专题 — 数据类型检测专题

1、typeof

检测数据类型

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call
  • 检测数据类型公共方法封装

js中的数据类型检测专题汇总

typeof

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

语法:typeof[value]

返回结果:首先是一个字符串,字符串中包含了我们需要检测的数据类型

typeof 12 => 'number'
typeof Nan => 'number'
typeof '' => 'string'

var flag = true;
typeof flag => 'booleanr'

typeof undefined => 'undefined'

function fn(n,m){
    if(typeof n==='undefined'){
        n=0
    }
}

typeof null => 'object' null虽然是基本类型值,但是它属于空对象指针,检测的结果是对象(局限性)

typeof {} => 'object'
typeof function(){} => 'function'

typeof [] => 'object'
typeof /^$/ => 'object'
//使用typeof有自己的局限性,不能具体细分出当前的值是数组还是正则(也就是不能细分对象类型的值)

typeof (1>1?0:2) => 'number'
typeof 1>1?0:2 => 2 //这里涉及到运算符优先级问题  先计算typeof 1 => 'number' => 'number'>1?0:2  所以typeof跟加减乘除问号一样属于逻辑运算符,多个运算符在一起会存在优先级问题

复制代码

面试题

typeof typeof [] => 'string' //先检测typeof []得到的结果是'object',再检测typeof 'object'=>字符串
复制代码

typeof是项目中非常常用的检测数据类型的方式,对于数,正则,不能细分对象类型(局限性)我们使用其他方式来做

2、instanceof和constructor

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

constructor:构造函数

使用instanceof检测某个值是否属于某一个数据类型的内置类,从而检查出它是否是这个类型的值;使用instanceof可以实现typeof实现不了的,对对象类型值详细的区分检测

[] instanceof Array => true
[] instanceof RegExp => false
复制代码

使用instanceof检测也有自己的弊端:

1、基本类型值无法基于它检测

//字面量创建
var num = 12;
num.toFixed(2) => "12.00" //说明:12是Number类的一个实例,因为它可以调取Number.prototype上的方法,但是它是一个基本类型值

// 构造函数创建
var num2 = new Number(12);
num2.toFixed(2) => "12.00" 

// 基本类型值通过字面量创建和构造函数创建,相同点都是Number类的一个实例,不同点一个是基本类型值,一个是引用数据类型值

typeof num => 'number'
typeof num2 => 'object'

//不管是哪一种方式创建基本类型值,都是自己所属类的实例(只不过类型不一样而已)

num instanceof Number => false
num2 instanceof Number => true
复制代码

为什么instanceof能检测num2检测不到num呢?如2、

2、instanceof检测的原理是基于原型链检测的:只要当前类在实例的原型链上,最后返回的结果都是true

var ary=[];
ary instanceof Array  // => true
ary instanceof Object // => true


function Fn(){}
Fn.prototype=new Array();//原型继承(Fn是Array的子类)
var f =new Fn();
console.dir(f)//打印出来的f并没有数组的length属性,不具备数据的基础结构
f instanceof Array // true 但是我们的f其实不应该是数组,虽然在它的原型上可以找到数组,但是它不具备数组的基础结构
//(数组有length属性,它没有),这也instanceof的弊端
复制代码

constructor

获取当前要检测数据值的constructor,判断它是否是某一个数据类型内置类来检测

var ary=[];
ary.constructor === Array; // true
ary.constructor === RegExp; //false
ary.constructor === Object; //false

ary.constructor='AA';
ary.constructor===Array // false

// constructor检测数据类型非常不可靠,因为这个属性是经常容易被修改的
复制代码

constructor检测数据类型非常不可靠,因为这个属性是经常容易被修改的

3、Object.prototype.toString

Object.prototype.toString.call([value]):获取Object.prototype上的toString方法,让方法中的this变为需要检测的数据类型值,并且让方法执行

在Number、String、Boolean、Array、Function、RegExp...这些类的原型上都有一个toString方法;这个方法就是把本身的值转换为字符串的

(12).toString // '12'
(true).toString // 'true'
[12,23].toString // '12,23'
复制代码

在Obeject这个类的原型上也有一个方法toString,但是这个方法并不是把值转换为字符串,而是返回当前值的所属类详细信息,固定结构:'[object 所属的类]'

var obj = {name:'哈哈'};
obj.toString() // "[object Object]" 调取的正是Object.prototype.toString

// obj.toString() 
// 首先执行Object.prototype.toString方法
// 这个方法中的this就是我们操作的数据值obj
// 总结:Object.prototype.toString执行的时候会返回当前方法中this的所属类信息

// 也就是,我想知道谁的所属类信息,我们就把这个toString方法执行,并且让this变为我们检测的这个数据值
// ,那么方法返回的结果就是当前检测这个值的所属类信息
复制代码

使用toString检测数据类型,不管你是什么值,我们都可以正常检测出需要的结果(这个方法检测是万能的)

Object.prototype.toString.call([value])
({}).toString.call([value])

Object.prototype.toString.call(12) // [object Number]
Object.prototype.toString.call(true)// [object Boolean]
Object.prototype.toString.call('')// [object String]
Object.prototype.toString.call(null)// [object Null]
Object.prototype.toString.call(undefined)// [object Undefined]
Object.prototype.toString.call({})// [object Object]
Object.prototype.toString.call([])// [object Array]
Object.prototype.toString.call(/^$/)// [object RegExp]
Object.prototype.toString.call(function(){})// [object Math]
Object.prototype.toString.call(Math)// [object Function]
Object.prototype.toString.call(document.body)// [object HTMLBodyElement]
Object.prototype.toString.call(document)// [object HTMLDocument]
复制代码

4、检测数据类型方法的封装

由于Object.prototype.toString检测数据类型方法写起来很长也很麻烦,所以封装一个

~function () {
    var obj = {
        isNumber: 'Number',
        isString: 'String',
        isBoolean: 'Boolean',
        isNull: 'Null',
        isUndefined: 'Undefined',
        isPlanObject: 'Object',
        isArray: 'Array',
        isRegExp: 'RegExp',
        isFunction: 'Function'
    };
    var check = {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            check[key] = (function (classValue) { // 把实参obj[key]传给形参classValue  实参是传递的值,形参是接收传递的值
                return function (val) {
                    return new RegExp('\\[object ' + classValue + '\\]').test(Object.prototype.toString.call(val));
                }
            })(obj[key]);
        }
    }
    window.check = check;
}();

console.log(check);
check.isNumber(12);
复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值