面试官:JS判断数据类型,原理?
关于js判断数据类型,会,但好像又不是完全会,在面试中总是被一些奇怪的问题搞得很狼狈。
但是有了这篇文章,妈妈再也不用担心面试被问到数据类型的问题了。
First blood
面试官:可以说一下js判断数据类型的方法吗?
我:判断基本数据类型可以用typeof,判断复杂数据类型可以用instanceof,它主要通过判断前者否为后者的实例对象来实现的。同时也可以使用Object.prototype.toString.call()方法和构造函数constructor来判断数据类型。
面试官:哦?那你知道instanceof是怎么判断前者是否为后者的实例化对象的吗,可以自己实现出来吗。
我:(自己写?请问您礼貌吗,还好我有所准备,根本没在怕的)
首先,a instanceof A ,主要是通过在a的原型链上一层一层去找,如果能找到A.prototype,就说明a是A的实例化对象。如果找到头都没有找到A.prototype,那就说明a不是A的实例化对象。那怎么能知道找到头呢?因为所有对象从原型链向上找,最后一个一定是null,倒数第二个是Object。所以我们可以说所有的对象都是Object的实例化对象。
如果不够清楚我们可以举个例子,例如我们创建一个数组的对象,我们看一下它的原型链的情况:
let arr = new Array() arr.__proto__ === Array.prototype // true arr.__proto__.__proto__ === Object.prototype // true arr.__proto__.__proto__.__proto__ === null // true 复制代码
有了这个思路我们就可以手动自己写一个instanceof方法了。
function myInstanceof(left,right){ if(typeof left !== 'object' || left === null){ return false; } let leftProto = left.__proto__ let rightProto = right.prototype while(true){ if(leftProto === null){ return false } if(leftProto === rightProto){ return true } leftProto = leftProto.__proto__ } } 复制代码
Double kill
面试官:说得不错,那你刚才说的Object.prototype.toString.call()是怎么做到能判断数据类型的呢?其中的prototype和call都是用来做什么的。
我:(够刁钻,但是我依旧可以的)
首先说一下为什么要以Object.prototype的这种写法,因为对于一些像数组,字符串类型的,它们已经重写了toString()方法
console.log('123'.toString()); // 123 console.log([1,2,3].toString()); //1,2,3 复制代码
所以我们才使用Object.prototype.toString()这种保险的方式来写。而这个方法会根据this来返回一个像'[object xxx]'这种形式的字符串,后面这个xxx就是this对象的类型。如果直接调用,那么就是Object的类型,返回的值也就是'[object Object]'
如果想要判断其他类型的对象,我们只要改变了调用这个方法的this对象,就可以获得改变后对象的类型了,那如何改变this的指向呢?我们可以在方法的后面加上一个call方法。
Object.prototype.toString.call('') ; // [object String] Object.prototype.toString.call(1) ; // [object Number] Object.prototype.toString.call(true) ; // [object Boolean] Object.prototype.toString.call(undefined) ; // [object Undefined] Object.prototype.toString.call(null) ; // [object Null] Object.prototype.toString.call({}) ; // [object Object] Object.prototype.toString.call([]) ; // [object Array] Object.prototype.toString.call(new Function()) ; // [object Function] Object.prototype.toString.call(new Date()) ; // [object Date] Object.prototype.toString.call(new RegExp()) ; // [object RegExp] Object.prototype.toString.call(new Error()) ; // [object Error] 复制代码
Triple kill
面试官:答的不错,那我给你出几个题做吧。都是和数据类型相关的,做一下试试
console.log(true + 0); console.log(true + 'abc'); console.log(true+true); console.log(true+false); console.log(null + 1); console.log(undefined + 1); console.log(undefined + '123'); console.log('1'>true); console.log('3'>true); console.log(1+'2'+false); console.log('2' + ['arr',1]); console.log(NaN == NaN); console.log(null == undefined); console.log(null === undefined); console.log(1 == true); console.log(0 === false); var p1 = { name: 'lisi', age: 20 } var p2 = { toString(){ return 'name:wangwu,age:18' } } console.log('嘻嘻' + p1); console.log('哈哈' + p2);
作者:Ln
链接:https://juejin.cn/post/7017697306652704798