今日题目:
题目解析:
我所知道并总结的数据类型判断方法一共有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 // RegExp
new 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)) // number
console.log(typeof('小石头')) // string
console.log(typeof(true)) // boolean
console.log(typeof(undefined)) // undefined
console.log(typeof(null)) // object
console.log(typeof(Symbol('唯一的石头姐'))) // symbol
console.log(typeof(999n)) // bigint
console.log(typeof({})) // object
console.log(typeof(Person)) // funtion
// 内置对象不可以细分
console.log(typeof([])) // object
console.log(typeof(/^\d{1,4}$/g)) // object
console.log(typeof new Date()) // object
// 自定义对象不可以细分
console.log(typeof new Person()) // object
总结:
- 判断null时会返回「’object’」(原理问题,见后边章节)
- 不能细分内置对象类型
- 常用来区分基本数据类型
typeof一个不存在的变量/属性,得到undefined(暂时性死区问题,见后边章节)
typeof adfadfadsf // undefined
var aaa = {}
typeof aaa.xxx // undefined
instanceof
可通过 instanceof 操作符来判断对象的具体类型,如果是指定类型返回 true,否则返回 false。
用法:
[] instanceof Array // true
总结:
因为其功能:只是判断指定对象是否在目标变量的原型链上,所以决定其局限性:
只能判断引用类型
- 但是可以细分自定义构造函数
- 若原型链被修改,将会导致判断不准确
撰写人:小石头