JS中的值类型
值类型
每个编程语言都需要变量,而变量都会有类型。在JS中,主要有两种类型:Primitive Value(aka: 基本类型)和Object(aka: 引用类型)。基本类型主要有:string、number、boolean、undefined、null、symbol(ES6新增基本数据类型)。而引用类型主要有:Date、Array、Function、RegEpx等等。
基本类型和引用类型的区别
基本类型和引用类型的最大区别在于:基本类型存储的就是该变量在内存中的值,而引用类型存储的是指向内存中存储值的内存的地址。考虑如下代码:
1 | // example_1.js |
同样是在赋值之后,改变赋值对象的原有的值。结果是prmValue_2
不受影响,obj_2
的值却和重新赋值后的obj_1
保持了一致。这就是基本类型和引用类型存储值的方式导致的结果。下面来拆解example_1.js
中的代码,来具体解释这段代码的为何会得到这样的结果。
1 | let prmValue_1 = 1; |
此时他们在内存中的关系如下图所示:
接着,执行以下代码:
1 | let prmValue_2 = prmValue_1; |
此时,内存中表示如下图所示:
可以看到,prmValue_1
和prmValue_2
分别存放了两个基本类型,值为1。而obj_1
和obj_2
都存放的是同一个内存块的地址的引用。再接着执行下面的代码:
1 | prmValue_1 = 2; |
此时,各个变量在内存中的表示如下图所示:
如图所示,此时的prmValue_1
存放的值是2,而obj_1
存放的地址引用则指向了另一个内存块。而obj_2
的地址引用与obj_1
指向的是同一个地址。所以,当obj_1
的内存地址指向变化的时候,obj_2
也会跟着一起变化。从而得到了上面的结果。
这就是基本类型与引用类型在赋值的时候,内存变化的全过程了。
类型判断
基本类型的判断可以用typeof
去判断值类型,但是引用类型用typeof
得到结果大部分的都是object
,当然也有例外,比如Function。
1 | // example_2.js |
所以,可以看到。用typeof去判断除null
以外的基本类型和function可以得知值的具体类型,但是其他就不行了。那么其他怎么去判断呢?
答案是Object.prototype.toString()
方法。类型判断结果如下:
1 | // example_3.js |
这样得到的结果值准确的,但是在可读性和代码复用上很不好。所以,可以全局建一个公共的judge/index.js
的文件,然后分别判断每个类型:
1 | // judge/index.js |
强制类型转换
在ES5以前,强制类型转换是一个很令人苦恼的问题,因为==、>=、<=、<、>
等操作符会把左右两边不是同一个类型的值强制转换成同一个类型,然后去做比较。即隐式强制类型转换。比如
1 | 13 == '13'; // true |
因为这一系列的隐式强制类型转换,可能会导致我们意想不到的结果,所以ES6引入了===
操作符,===
不会在比较左右两边的值的时候,将两边的值类型强制转换成同一个类型。因为===
是比较value && type
的。隐式强制类型转换有很多坑,可以单开,这里先埋坑。
除了隐式强制类型转换,还有显示强制类型转换,强制类型转换是我们主动去调用一些方法,将一个值类型转换成我们预期的值类型的方法,这种方法是可控的,所以,相较于隐式强制类型转换来说,显示强制类型转换安全的多。
1 | // 显示强制类型转换 |
可以看到,强制类型转换只存在于基本类型之间的转换,不要在非基本类型之间做强制类型转换,因为结果不可控。
原文作者: Billy & Barney
原文链接: https://liangbilin.github.io/2019/12/30/Barney--JS中的值类型/
版权声明: 转载请注明出处(必须保留作者署名及链接)