JS手写代码之数据类型判断 typeof

1,961 阅读2分钟

前言:

对数据类型进行判断是我们在日常敲代码的过程中时常会遇到的,而JS中的数据类型判断方法共有四种,分别是typeof、toString、constructor和instanceof,而我今天要介绍的就是其中之一,typeof。

首先,我们要明确ES6中的数据类型分为两种:基本类型和引用类型

  • 基本类型:即简单的数据段,都是按值访问的,即将一个基本类型的数据赋值给另外一个变量,是通过将原数据拷贝一份赋值的,两变量之间互不影响。

  • 引用类型:即保存在内存中的对象,按引用访问,即将一个引用类型的地址赋值给另一个变量,当该变量改变时,原变量也会随之改变。

  • 基本类型有:Undefined,Null,Boolean,Number,String

  • 引用类型第一类:原生对象(ECMAScript本身自带对象):object,Array,Date,RegExp,Function

手写一个简单例子:

console.log(typeof 2) //输出 number  
console.log(typeof null) //输出 object  
console.log(typeof {}) //输出 object  
console.log(typeof []) //输出 object 
console.log(typeof (new Date)) // 输出 object 
console.log(typeof (function(){})) //输出 function  
console.log(typeof undefined) //输出 undefined  
console.log(typeof '222') //输出 string  
console.log(typeof true)//输出 boolean

我们很明显地可以看出typeof可以正确识别Undefined、Boolean、Number、String、Symbol、Function等数据类型,但是在数组,日期,对象上的判断确并不准确,都是返回object,这是为什么呢?

答案就在于,引用类型中,除了function返回function类型外,其他均返回object。其中,null 有属于自己的数据类型 Null , 引用类型中的 数组、日期等也都有属于自己的具体类型,而 typeof 对于这些类型的处理,只返回了处于其原型链最顶端的 Object 类型,没有错,但却不是我们想要的结果。

而解决这个问题的方法就是: Object.prototype.toString()

手写代码:

function typeOf(obj) {    
let res=Object.prototype.toString.call(obj).split('')[1]    
res=res.substring(0,res.length-1).toLowerCase()    
return res}
typeOf([]); // 输出 array 
typeOf({}); // 输出 object
typeOf(new Date); // 输出 date

首先在Object.prototype.toString()方法被调用时,会执行下面的操作步骤:

 1. 获取对象的[[Class]]属性的值。2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串。3. 返回第二步的操作结果Result(2)。 [[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性,在规范中,[[Class]]是这么定义的,并且[[Class]]属性的值可以是除了 "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串。

所以通过Object.prototype.toString()方法,我们就能够检测判断出typeof方法无法准确判断的对象的类型了。

总结

在JS的领域中,我还只是个萌新,写的东西还比较浅显,还望各位大佬看后多多指正!