今日题目:
题目解析:
我所知道并总结的数据类型判断方法一共有4种,他们分别是:
- Object.prototype.toString
- constructor
- typeof
- instanceof
接下来我就具体说说这四种方法的用法和原理吧?
得到面试官示意:
- 不用了 -> 下一题吧
- 微笑不说话并点头 -> 则继续向下文展开整个篇章:
- 嗯,你可以具体说说xxx -> 说具体的方法的原理和深度剖析,请看后续篇章
Object.prototype.toString
首先,我们可以直接使用Object.prototype.toString来进行判断。因为他可能是这几个方法里可以开箱即用、且判断类型最完善的一个方法了。
用法:
Object.prototype.toString.call(target) // 这里也可以用apply来改变this指向。
不用类型判断结果合集:
function Person() {}Object.prototype.toString.call(2020) // [object Number]Object.prototype.toString.call('小石头') // [object String]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(Symbol('唯一的石头姐')) // [object Symbol]Object.prototype.toString.call(999n) // [object BigInt]Object.prototype.toString.call({}) // [object Object]Object.prototype.toString.call(()=>'xing.org1^') // [object Function]// 内置对象可以细分Object.prototype.toString.call([]) // [object Array]Object.prototype.toString.call(/^\d{1,4}$/g) // [object RegExp]Object.prototype.toString.call(new Date()) // [object Date]// 自定义对象不能细分类型Object.prototype.toString.call(new Person()) // [object Object]
总结
- 可以判断出所有类型
-
constructor
除了undefined和null外,我们可以利用原型链,找到变量构造函数的name值来判断类型。
用法
'小石头'.constructor.name // String({}).constructor.name // Object// 可以细分自定义对象类型function Person() {}(new Person()).constructor.name // Person

不用类型判断结果合集:
function Person() {}(2020).constructor.name // Number('小石头').constructor.name // String(true).constructor.name // Boolean// (undefined).constructor.name // 报错 TypeError: Cannot read property 'constructor' of undefined// (null).constructor.name // 报错 TypeError: Cannot read property 'constructor' of undefined(Symbol('唯一的石头姐').constructor.name) // Symbol(999n).constructor.name // BigInt({}).constructor.name // Object(Person.constructor.name) // Function// 内置对象可以细分([]).constructor.name // Array(/^\d{1,4}$/g).constructor.name // RegExpnew Date().constructor.name // Date// 自定义对象可以细分new Person().constructor.name // Person
总结:
因为调用undefined和null身上的属性会报错,所以需要先判断,剔除这两者。
- 可以细分内置对象
- 可以细分自定义对象
- 但原型链可能被修改,导致判断不准确
代码封装如下:
function getConstructor(target){if(target == undefined) return target // 利用“双等”时,undefined和null一致else return target.constructor.name}
typeof
用法:
typeof '小石头' // ’string‘typeof('小石头') // 第二种写法typeof undefined // ’undefined‘
不用类型判断结果合集:
function Person() {}console.log(typeof(2020)) // numberconsole.log(typeof('小石头')) // stringconsole.log(typeof(true)) // booleanconsole.log(typeof(undefined)) // undefinedconsole.log(typeof(null)) // objectconsole.log(typeof(Symbol('唯一的石头姐'))) // symbolconsole.log(typeof(999n)) // bigintconsole.log(typeof({})) // objectconsole.log(typeof(Person)) // funtion// 内置对象不可以细分console.log(typeof([])) // objectconsole.log(typeof(/^\d{1,4}$/g)) // objectconsole.log(typeof new Date()) // object// 自定义对象不可以细分console.log(typeof new Person()) // object
总结:
- 判断null时会返回「’object’」(原理问题,见后边章节)
- 不能细分内置对象类型
- 常用来区分基本数据类型
typeof一个不存在的变量/属性,得到undefined(暂时性死区问题,见后边章节)
typeof adfadfadsf // undefinedvar aaa = {}typeof aaa.xxx // undefined
instanceof
可通过 instanceof 操作符来判断对象的具体类型,如果是指定类型返回 true,否则返回 false。
用法:
[] instanceof Array // true
总结:
因为其功能:只是判断指定对象是否在目标变量的原型链上,所以决定其局限性:
只能判断引用类型
- 但是可以细分自定义构造函数
- 若原型链被修改,将会导致判断不准确
撰写人:小石头
