JS现有数据类型
在了解如何判断数据类型之前,我们首先要明确现在JavaScript中有几种数据类型。
JavaScript中数据类型分为两类:基本数据类型和引用数据类型。基本数据类型包括:Boolean
、String
、Number
、Null
、Undefined
、Symbol(ES6新增)
、BigInt(ES6新增)
七种。引用数据类型包括:Object
、Function
、Array
、Date
、RegExp
五种。一张图概括:
typeof
typeof
一般用于判断基础类型,它的具体用法是:
typeof variable
它会返回一个字符串,表示给定变量的类型。它能正确判断除了Null以外的六种基础类型。
console.log(
typeof true, //'boolean'
typeof 'hi', //'string'
typeof 100, //'number'
typeof undefined, //'undefined'
typeof Symbol(), //'symbol'
typeof 100n //'bigint'
typeof null //'object'
);
从上面的代码可以看出,除了null以外,typeof都做出了正确的判断。却偏偏对null返回了object。
造成这一异常的原因是:
在JavaScript的最初版本中,使用的是32位系统,为了性能考虑使用低位存储了变量的类型信息,000开头代表是对象,然而null表示为全0,所以将它错误的判断为对象。
虽然现在的内部类型判断代码已经改变了,但这个Bug却一直流传下来。
对引用类型使用typeof时,对Function类型返回'function',对其他四种类型都返回'object'。
instancof
instanceof
通常用于判断一个对象到底是哪种引用类型,它的具体用法是:
object instanceof constructor
object
是某个对象实例,constructor
是某个引用类型的构造函数。如果object
是给定引用类型(constructor
)的实例,则返回true;否则返回false。
[] instanceof Array; //true
{} instanceof Object; //true
new Date() instanceof Date; //true
原理:instanceof
是根据给定对象实例的原型链进行判断的,它会检测给定构造函数的prototype属性是否出现在这个实例的原型链上。如果出现了,则返回true;否则返回false。
优点:根据原理也可以看出instanceof
的优点,即instanceof
不仅可以判断一个对象是否是某个原生引用类型的实例,也可以判断它是否是某个自定义类型的实例。
缺陷:如果网页中包含多个框架,就存在多个不同的全局环境,不同的全局环境拥有不同的全局对象。由于Object
、Array
等构造函数是window对象
的属性,所以Object
、Array
等构造函数也存在不同的版本。
这导致如果将一个对象从一个全局环境传到另一个全局环境中,instanceof
的判断会出错。比如:
//test1.html
<iframe src="./test2.html"></iframe>
<script>
Array === window.frames[0].Array; //false
let arr = [];
arr instanceof Array; //true
arr instanceof window.frames[0].Array; //false
</script>
可以看出,由于不同全局环境下,构造函数存在不同的版本。导致instanceof
对同一个对象实例的判断出现了不同的结果。
Object.prototype.toString.call()
Object.prototype.toString.call(anyValue);
在任何值上调用Object原型对象上的toString方法,都会返回一个'[Object NativeConstructorName]'
的字符串。这个NativeConstructorName
是某个原生构造函数的名称,也就是该值的类型。
Object.prototype.toString.call(''); //[object String]
Object.prototype.toString.call(100); //[object Number]
Object.prototype.toString.call([]); //[object Array]
Object.prototype.toString.call(new RegExp()); //[object RegExp]
原理:每个类在内部都有一个[[Class]]
属性,这个属性就指定了NativeConstructorName
。因为原生数组的构造函数名与全局作用域无关,因此这个方法弥补了instanceof
的缺陷。
优点:它能正确地返回某个变量的类型,不管是基本类型还是引用类型。
缺点:对于引用类型,它只能判断出原生引用类型的实例。对于任何自定义的类型,它永远返回'[object Object]'
。
参考文档:
instanceof - JavaScript | MDN
《JavaScript高级程序设计》
如果感到这篇文章对你有用,麻烦点个赞~