JS数据类型 使用工具方法区分各种数据类型

JS数据类型

js有8种数据类型,其中7种为基础类型(原始值),1种为引用类型(引用值)
基础类型:undefined、Null、Boolean、String、Number、BigInt、Symbol
引用类型:Object(Array、RegExp、Date、Math、Function)

基础类型存储在栈内存中,被引用或被拷贝时,会创建一个完全相等的变量

引用类型存储在堆内存中,存储的是地址,被引用或被拷贝时,可能会出现多个引用指向同一个地址,这涉及到“共享”的概念

区分数据类型的几种方法

1.typeof
typeof可以区分除null之外的原始数据类型

注:typeof null结果为object ,但null不是对象,这是js存在已久的问题,所有的值在计算机中都以二进制编码储存,浏览器种把二进制前三位为000的当作对象,而null的二进制前三位为000,故被识别为了对象,其实不然,它是空对象指针,所以typeof null为object不能作为判断null的方法,如需在if语句中判断是否为null,直接通过===null来判断即可

NaN/Infinity都是数字类型,检测结果为"number"

typeof只能判断出function这一类的引用值,其余均显示"object"

2.instansceof
instanceof可以判断左边实例对象是否是由右边构造函数生成的,即左边对象是否是右边构造函数 原型链继承 的对象,构造函数的原型只要出现在实例对象的原型链上就返回true

实例对象必须是对象数据类型的,基本数据类型的实例无法检测,即instanceof只能判断引用值,不能判断原始值

字面量方式创建的不能检测,构造函数创建的可以检测

无法判断是否是普通对象,不管是数组对象还是正则对象,都是Object的实例,都会返回true

/instanceof的底层实现代码
/
function myInstanceof(left,right){
	//instanceof无法判断基本数据类型,所以开头直接pass
	if(typeof left !== "object" || typeof left === null) return false;
	//构造函数的原型只要出现在实例对象的原型链上就返回true
	let proto = Object.getPrototypeOf(left);//getPrototypeOf是Object对象自带的API,能够得到参数的原型对象
	while(1){
		if(proto === null) return false;
		if(proto === right.prototype) return true;
		proto = Object.getPrototypeof(proto);
	}
}
console.log(myInstanceof(new Number(123), Number));//true
console.log(myInstanceof(123, Number));//false

3.constructor
判断当前实例的constructor属性值是不是对应的构造函数
实例.constructor === 类 属于返回true,否则返回false
可以检测基本数据类型

不能重定向当前构造函数的原型,否则会造成检测结果不准确
不能给当前实例添加私有属性constructor,否则会造成检测结果不准确
js中的构造函数原型的constructor是不被保护的,用户可以进行修改,因此基于constructor检测的值存在不确定性

不管是单独使用typeof、instanceof、constructor,都不能满足所有场景的需求,而多者混写的方式判断出来的其实也只是大多数的情况,并且写起来比较难受,因此,更加推荐下面的第四种方法

4.Object.prototype.toString.call()({}).toString.call()
此方法是基于js本身专门进行数据检测的,是目前检测数据类型比较好的方法

这里的toString()是Object的原型上的方法,可判断原始值,也可判断引用值,输出格式为"[object Xxx]"的字符串
每种数据类型的构造函数的原型上都有toString方法,除了Object.prototype上的toString方法是用于返回当前实例所属构造函数的信息,其余的都是转换为字符串的

对于Object对象,直接调用toString()就能返回[object Object]
对于其他对象需要通过call调用,才能返回正确的类型信息

对象实例.toString() toString()方法中的this指向实例对象,即检测的是对象实例的数据类型,Object.prototype.toString.call()就是用call方法将toString方法中的this 指向要检测的数据

只能检测内置类,不能检测自定义类,自定义类会返回[Object Object]

工具方法思路

  1. 排除null,null虽然是原始值,但由于js的历史遗留问题,其数据类型为object
  2. typeof 区分原始值(也叫基本数据类型:Number、String、Boolean、Null、Undefined)和引用值(如Object,Function,Array,RegExp,Data等)
  3. Object.prototype.toString.call() 细分引用值

代码实现

 var test = function(e){
 	var ret = typeof e;
    var template = {//引用值对象
      '[object Array]':'array',//数组
      '[object Object]':'object',//对象
      '[object Number]':'number-object',//包装类
      '[object Boolean]':'boolean-object',//包装类
      '[object String]':'string-object',//包装类
      '[object Date]':'date-object',//日期
      '[object RegExp]':'regexp-object'//正则表达式
    }
    if(e == null){//判断是否为null/undefined undefined == null为true
      return e;
    }else if(ret == 'object'){//引用值
      var str = Object.prototype.toString.call(e);
      return template[str];
    }else{//原始值
      return typeof(ret)
    }
  }

测试

在这里插入图片描述在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值