JavaScript基础面试题3--typeof 与 instanceof 区别

JavaScript基础面试题3--typeof 与 instanceof 区别

    • 前言
    • 1. typeof
    • 2. instanceof
    • 3.区别
    • 4.实现全局通用数据类型判断方法

前言

1. typeof

typeof操作符返回的是一个字符串,表示未经计算的操作符类型
例:

	typeof 1 // number
	typeof '1' // string
	typeof undefined // undefined 
	typeof true // boolean
	typeof Symbol() // sumbol
	typeof [] //objrct
	typeof {} // object
	typeof console // object
	typeof console.log // function
	typeof null // object
  • 上面的例子当中,前面五个是基本数据类型。最后一个 typeof nullobject,这是JavaScript存在的一个悠久历史 Bug ,不代表 null 就是引用数据类型,而且 null 本身也不是对象。
  • nulltypeof 之后返回的是有问题的结果,不能作为判断 null 的方法。如果需要在 if 语句中判断是否为 null,直接通过 === null 进行判断。
  • 引用类型若使用 typeof 进行判断,除了 function 会被识别外,其余全部输出 object
  • 如果要判断一个变量是否存在,可以使用 typeof。(若使用 if(a),且 a未声明,则会报错)
	if(typeof a != 'undefined'){
		// 变量存在
	}

2. instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。构造函数通过 new 可以实例化对象,instanceof 能判断这个对象是否是之前那个构造函数所生成的对象。

	let Student = function () {}
	let s1 = new Student();
	console.log(s1 instanceof Student);  // true
	
	let str = 'Hello'
	console.log(str instanceof String) // false

这里模拟 instanceof 实现原理:

	function myInstanceof (leftObj,rightObj){
		// 先使用 typeof 判断是否为基本类型  如果是直接返回 false
		if(typeof leftObj !=='object'  || leftObj === null){
			return false;
		}
		// getProtoTypeOf 是Object 自带的 API, 能够获取到参数的原型对象
		let proto = Object.getProtoTypeOf(leftObj);
		while(true){
			if(proto === null) return false;
			// 找到相同的原型对象, 返回 true
			if(proto === rightObj.prototype) return true;
			// 顺着原型链去找,直到找到相同的原型对象
			proto = Object.getProtoTypeOf(proto);
		}
	}

	let Student = function (){}
	let s1 = new Student()
	console.log(myInstanceof(s1,Student)) //true

3.区别

typeofinstanceof 都是判断数据类型的操作符,区别如下:

  • typeof返回一个变量的基本类型,instanceof 返回的是一个布尔值;
  • instanceof 可以准确的判断复杂引用数据类型,但是不能正确判断基本数据类型;
  • typeof 虽然可以判断基本数据类型(null 除外),但是引用类型除了 function 可以识别,其他类型都无法判断。

4.实现全局通用数据类型判断方法

若需要通用的检测数据类型,可以采用 Object.prototype.toString ,调用该方法时,统一返回格式为 [Object Xxx] 的字符串。这里的 .call() 会改变toString 方法内部的 this 指向,使其指向传递的参数。因此会返回要查看参数类型。

	Object.prototype.toString({})                            // "[object Object]"
	Object.prototype.toString.call({})                       // "[object Object]"
	Object.prototype.toString.call(10)                       // "[object Number]"
	Object.prototype.toString.call('10')                     // "[object String]"
	Object.prototype.toString.call(false)                    // "[object Boolean]"
	Object.prototype.toString.call(function () {})           // "[object Function]"
	Object.prototype.toString.call(() => {})                 // "[object Function]"
	console.log(Object.prototype.toString.call(null));       // "[object Null]"
    console.log(Object.prototype.toString.call(undefined));  // "[object Undefined]"
    console.log(Object.prototype.toString.call(/abc/g));     // "[object RegExp]"
    console.log(Object.prototype.toString.call([]));         // "[object Array]"

根据上面的调用形式,实现一个全局通用的数据类型判断方法:

function getObjType (obj){
	// 判断若为基本类型 直接返回
	if (typeof obj !== 'object'){
		return typeof obj;
	}
	// 正则构建返回具体类型
	return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/,'$1'));
}

你可能感兴趣的:(JavaScript,面试题,javascript,开发语言,ecmascript)