js封装一个判断数据类型的函数

文章目录

      • typeof
      • instanceof
      • constructor
      • Object.prototype.toString()
      • 到最后了,封装一个准确判断数据类型的函数。

有些同学面试上会经常遇到这个笔试题—用js手写一个判断数据类型的函数。
当然了这个题方法有好多种…但是你有木有想哪种写法比较简单。如果你还在 if…else if…else if…else…你就out了。
但是都是基于----typeofinstanceofconstructorObject.prototype.toString()它们来展开的一系列写法。
那么你真的了解他们每一个各自的用法吗?你最终写出的函数判断准确吗?

不着急,咱们一个一个来操作一哈。


typeof

typeof 操作符返回一个字符串(全小写字母),表示未经计算的操作数的类型。

用法可以是 typeof operandtypeof(operand)
operand 一个表示对象或原始值的表达式,其类型将被返回。


	//数值
	console.log(typeof 1);   //number
	console.log(typeof 1.11);   //number
	console.log(typeof(1));   //number
	console.log(typeof Math.PI);   //number
	console.log(typeof Infinity);   //number
	console.log(typeof NaN);   //number
	console.log(typeof Number(1));   //number
	
	//字符串
	console.log(typeof "");  //string
	console.log(typeof "abc");  //string
	console.log(typeof "1");  //string
	console.log(typeof (typeof 1));  //string
	console.log(typeof String(1));  //string
	
	//布尔值
	console.log(typeof false); //boolean
	console.log(typeof true); //boolean
	console.log(typeof Boolean(1)); //boolean
	console.log(typeof !!(1)); //boolean

	//Symbol
	console.log(typeof Symbol()); //symbol
	console.log(typeof Symbol('foo')); //symbol
	console.log(typeof Symbol.iterator); //symbol

	//undefined
	console.log(typeof undefined); //undefined

	//函数
	console.log(typeof function(){}); //function
	console.log(typeof class C{}); //function
	console.log(typeof Math.min); //function
	
	//对象
	console.log(typeof {}); //object
	console.log(typeof null); //object
	console.log(typeof []); //object
	console.log(typeof new Date()); //object
	console.log(typeof new RegExp()); //object
	// 下面的例子令人迷惑,非常危险,没有用处。避免使用它们。
	console.log(typeof new Boolean(true)) //object
	console.log(typeof new Number(1)) //object
	console.log(typeof new String('abc')) //object

instanceof

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

语法 [对象] instanceof [构造函数]

instanceof用来判断A是否为B的实例,表达式为:A instanceof B,如果AB的实例,则返回true,否则返回falseinstanceof检测的是原型,内部机制是通过判断对象的原型链中是否有类型的原型。

	console.log({} instanceof Object); //true
	console.log([] instanceof Array);  //true
	console.log([] instanceof Object); //true
	console.log("123" instanceof String); //false
	console.log(new String(123) instanceof String); //true

我们来实现一下 instanceof

	function _instance(L,R){
		let prototype = R.prototype; //原型
		let proto = L.__proto__; //隐式原型
		while(true){  //循环判断对象的原型是否等于隐式原型,直到对象原型为null,因为原型链最终为null
			if(proto === null || proto === undefined){ //当到达proto原型链顶端还未匹配,返回false
				return false;
			}
			if(proto === prototype){ //全等时,返回true
				return true;
			}
			proto = proto.__proto__;
		}
	}
	console.log(_instance({},Object)); //true
	console.log(_instance([],Number)); //false

constructor

对象的constructor属性用于返回创建该对象的函数,也就是我们常说的构造函数

语法 object.constructor

	console.log(''.constructor === String)	//true
	console.log(true.constructor === Boolean)	//true
	console.log(new Number(1).constructor === Number)	//true
	console.log(new Function().constructor === Function)	//true
	console.log(new Date().constructor === Date)	//true
	console.log(new Error().constructor === Error)	//true
	console.log([].constructor === Array)	//true
	console.log(document.constructor === HTMLDocument)	//true
	console.log(window.constructor === Window)	//true

Object.prototype.toString()

toString()是Object原型对象上的方法,返回的是代表该对象的字符串。

调用该方法,默认返回当前对象的[[Class]],这是一个内部属性,其格式为[object Xxx],其中Xxx就是对象的类型。

而对于Object对象,直接调用toString()就能返回[object Object],而对于其他对象(Array、String、Number、Boolean、RegExp、Date等),则需要通过call、apply来调用才能返回正确的类型信息。

: 因为Array、String、Number、Boolean、RegExp、Date等类型都重写toString(),如果直接调用则因为自身的原型对象上已有toString()方法,就不会调用到Object原型对象上的toString()方法了。

Object.prototype.toString()与Object.toString()的区别

  • Object.toString()的toString()是Object构造函数上的方法,返回的是对应的函数
  • Object.prototype.toString()的toString()是Object原型对象上的方法,返回的是代表该对象的字符串

+++ ok—回归正题

	//判断基本类型
	Object.prototype.toString.call(null);  //"[object Null]"
	Object.prototype.toString.call(undefined);  //"[object Undefined]"
	Object.prototype.toString.call(“abc”);  //"[object String]"
	Object.prototype.toString.call(123);  //"[object Number]"
	Object.prototype.toString.call(true);  //"[object Boolean]"

	//判断引用类型
	Object.prototype.toString.call(new Function());  //"[object Function]"
	Object.prototype.toString.call(new Date());  //"[object Date]"
	Object.prototype.toString.call(new Array());  //"[object Array]"
	Object.prototype.toString.call(new RegExp());  //"[object RegExp]"
	Object.prototype.toString.call(new Error());  //"[object Error]"


	Object.prototype.toString.call(document);  //"[object HTMLDocument]"
	Object.prototype.toString.call(window);  //"[object Window]"

	//判断JSON对象
	Object.prototype.toString.call(window.JSON);  //"[object JSON]"

到最后了,封装一个准确判断数据类型的函数。

	function getType(data){
		let type = typeof data;
		if(type !== "object"){
			return type
		}
		return Object.prototype.toString.call(data).replace(/^\[object (\S+)\]$/,'$1')
	}

这里用到正则以及String对象的replace方法,replace详细看w3c
或者MDN

你可能感兴趣的:(javascript,web前端面试指南)