今天面试问到了JS的数据判断,很遗憾我没有回答出,这里我做一下总结。
JavaScript的七种基本数据类型:
基本数据类型:Undefined,Null,Symbol,Number,String,Boolean引用类型:Object
这两者的区别在于,一个是在内存中存储变量的值,另一个是在内存中存储变量的地址值。
typeof
对各种类型给出typeof的各种解答:
typeof undefined --- undefined
typeof null --- object
typeof number --- number
typeof string --- string
typeof symbol --- symbol
typeof boolean --- boolean
typeof object --- object
typeof array --- object
typeof function --- fn(){} 这里如果是箭头函数,返回 ()=>{}
很遗憾,这里null,object,array都是返回 object
instanceof
用这个方法,能解决null,array,object的分别问题。
null instanceof Object --- false
object instanceof Object --- true
array instanceof Object --- true
至此,null的问题已经被彻底解决了
array instanceof Array --- true
object instanceof Array --- false
至此,array和object的问题也就被解决了
但是还存在问题,比如Date这种复杂的变量类型,它的instanceof也是Object,但是它是特殊的对象,还是无法检查出来问题。
constructor
这里的constructor又是一种新的方法,翻译为构造器,就是判断这个变量是由什么构造出来的。 请看代码:
const date = new Date();
const arr = []
const obj = {}
console.log(date.constructor === Date); // true
console.log(arr.constructor === Date); // false
console.log(obj.constructor === Date); // false
此时对于复杂的变量,我们也已经解决了问题。但是要注意,这个方法对于继承类的变量判断并不是很有效果
class A {
a(){
console.log("a")
}
}
class B extends A{
b(){
console.log("b")
}
}
const b = new B()
console.log(b.constructor === B); // true
console.log(b.constructor === A); // false
可以看到,此时得到了我预计是想得到两个true,但是判断他的继承类的时候,却发生了错误。但是instanceof方法却不会报错。所以很多时候,这两种方法要互相进行掺杂着使用
Object.prototype.toString.call
如果要彻底解决数据类型的判断,我们采用Object.prototype.call。call可以定义this的值,此时我们用this传入当前的数据,这样就能返回想要的结果了,给出代码:
console.log(Object.prototype.toString.call(1)); --- [object Number]
console.log(Object.prototype.toString.call("1")); --- [object String]
console.log(Object.prototype.toString.call(true)); --- [object Boolean]
console.log(Object.prototype.toString.call(null)); --- [object Null]
console.log(Object.prototype.toString.call(undefined)); --- [object Undefined]
console.log(Object.prototype.toString.call(function a() {})); --- [object Function]
console.log(Object.prototype.toString.call(() => {})); --- [object Function]
console.log(Object.prototype.toString.call([])); --- [object Array]
console.log(Object.prototype.toString.call({})); --- [object Object]
此时就能完成所要做的需求了,这里为什么需要Object.toString.call()而不是toString呢?因为数字,字符串toString时候,会得出当前字符的值而不是我们想要的,所以我们用Object对象上的方法,很快就能得出结果。 这里我尝试对这个方法进行封装,迅速判断是哪个类型。
function _isTypeof(value){
const type = Object.prototype.toString.call(value);
return type.match(/\[object (.*?)]/)[1].toLowerCase();
}
这个方法到目前为止用的没啥问题。
isArray,isNaN
还有就是这些比较细碎的知识点,isArray是array的一个判断方法,可以对是否是对象是否是array进行判断。isNaN是number的一个判断方法,可以判断对象是不是无穷大或者无穷小