这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
!
从一道面试题说起,js的数据类型有哪些?如何判断数据类型以及各个方法的优缺点
js数据类型
-
基本数据类型:字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol
Symbol 是 ES6 引入了一种新的原始数据类型,表示独一无二的值
-
引用数据类型:对象(Object)、数组(Array)、函数(Function)
数组类型判断方法
-
(1).typeof:
typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算
typeof运算符的返回类型为字符串,值包括如下几种:
1. 'undefined' --未定义的变量或值
2. 'boolean' --布尔类型的变量或值
3. 'string' --字符串类型的变量或值
4. 'number' --数字类型的变量或值
5. 'object' --对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理)
6. 'function' --函数类型的变量或值
复制代码
对于基本数据类型来说,除了null返回的是object,其他都可返回正确的类型适用于判断(除null)基础类型,判断引用类型,除了function 全返回object类型
-
(2).instanceof
只能用来判断变量的原型链上是否有构造函数的prototype属性(两个对象是否属于原型链的关系),不一定能获取对象的具体类型
instanceof 不适用判断原始类型的值,只能用于判断对象是否从属关系 -
(3).constructor
每一个实例对象都可通过constructor来访问它的构造函数,其实也是根据原型链的原理来的。由于undefined和null是无效的对象,因此是没有constructor属性的,这两个值不能用这种方法判断
-
(4)Object.prototype.toString.call
扩展:为什么Object.toString()的结果和Object.prototype.toString.call(obj)的结果不一样?
这是因为toString为Object的原型方法,而Array 、Function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(Function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串…..),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法
总结:
typeof 适合基本类型和function类型的检测,无法判断null与object
instanceof 适合自定义对象,也可以用来检测原生对象,在不同的iframe 和 window间检测时失效,还需要注意Object.create(null)对象的问题
constructor 基本能判断所有类型,除了null和undefined,但是constructor容易被修改,也不能跨iframe使用
tostring能判断所有类型,可将其封装为全能的DataType()判断所有数据类型