前言
相信不管是在开发还是在巩固基础的时候,js中的类型都是必须要知道的部分。并且由于js是还在数据计算和比较的过程中还存在数据类型的转换,所以这个不定的数据类型还是很头疼的。但是就算很头疼,js中的数据转换也有规律可循的,这里就从基础出发梳理下js的数据类型和数据类型的转换规则,一方面加深自己的记忆,另一方面希望能够帮助到大家。
内置的数据类型
一般说来js的内置数据类型总体分为两类:基础数据类型和引用数据类型
基础数据类型
- undefined
- null
- boolean
- string
- number
- symbol
- bigInt
引用数据类型
- Object
- Array
- RegExp
- Date
- Math
- Function
基础数据类型和引用数据类型的区别
基础数据类型:基础数据类型存储在栈内存中,被引用或者拷贝时,会创建一个完全相等的变量。占据的内存空间小,大小固定。属于被频繁使用的数据,所以会放在栈中存储。
引用数据类型:应用数据类型存储在堆内存中,而堆内存的地址指向的指针是存在栈中的。多个引用指向同一个堆内存地址。引用数据类型占据的空间搭,大小不固定。栈内存中存储的指针指向堆内存地址。当需要用到引用类型的值时,会去找栈中的地址然后通过地址找到真正的数据。
数据类型的判断方法
typeof
一般typeof用来判断基础数据类型,除了null都可以显示正确的数据类型
// number
typeof 1
// boolean
typeof false
// string
typeof 'water'
// undefined
typeof undefined
// object
typeof null
因为一些历史原因会把null判断为object,想知道原因的老铁可自行搜索查阅。而且当用typeof来判断引用类型的时候,除了函数会显示function外,其他的都会显示object。所以想要判断引用类型这个就不可以用了。
instanceof
instanceof可以正确的来判断对象的类型,因为内部使用的原理是通过判断对象的原型链中是不是能找到类型的prototype
[] instanceof Array
function() {} instanceof Function
{} instanceof Object
以上判断都为true,由此可见instanceof可以准确的判断出引用数据类型,但是不能正确判断出基础数据类型
constructor
1.constructor === Number
true.constructor === Boolean
'water'.constructor === String
[].constructor === Array
(function() {}).constructor === Function
{}.constructor === Object
正常的都能都来判断出各自的类型,但是又一个例外情况,就是如果你手动修改了原型,那么这个方法就不能准确判断数据类型了。
比如:
function Fn() {}
Fn.prototype = new Array()
const func = new Fn()
f.constructor === Fn // false
Object.prototype.toString.call
调用这个方法可以返回[Object xxx]的字符串,其中就可以通过xxx来判断各种的数据类型。
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
小结
-
typeof- 在计算机底层基于数据类型的值进行判断(一般是一些二进制数据)
typeof null判断为object的原因是对象存在计算机中,都是以000开始的二进制,所以判断为对象typeof判断引用类型都是objecttypeof NaN === 'number'
-
instanceof- 检测当前实例是否属于这个类的
- 底层机制:只要当前类出现在实例的原型上,结果都是true
- 不能检测基本数据类型
-
constructor- 支持基本类型
- constructor可以随便改,也不准
-
Object.prototype.toString.call([val])- 返回当前实例所属类信息