一说到js的数据类型脑海里是不是就蹦出来了null,undefined,string,boolean,number,Object,symbol,bigInt
下面我们具体去了解这几种数据类型
数据类型分为两种,一种原始类型,一种对象类型:
1.原始类型
null:只包含一个值:null,非自然赋值
undefined:只有一个值就是undefined,自然赋值
string:一串表示文本值的字符序列
boolean: 有两个字面值:true和false,表示一个逻辑实体
number:包括整数和浮点数
symbol:每次创建的值都是唯一的,不能被强制转换
2.对象类型
对象类型一些常用的Array,Funcion,Object都属于特殊的对象类型
为什么要这么去进行分类呢?原因就是原始类型的值是不可修改的
这时候你可能会说string提供的那些方法不就是用来改变string的吗,这不是可修改的?
是的,值确实改变了,大家都知道值是存储在栈和堆内存中的
栈内存的特点:
存储的值大小固定
空间较小
由于栈内存大小是固定的,所以在定义变量的时候大小已经决定了,你去修改它实际上是从新开辟了一片空间让修改的那个变量指向这个空间
堆内存的特点:
存储的值大小不定,可动态调整
空间较大,运行效率低
无法直接操作其内部存储,使用引用地址读取
注意这个引用地址,对象类型的值是存储在堆中的,而它的栈中会存储一个地址,这个地址指向的就是堆所在的内存,所以我们一般称对象类型为引用数据类型
这也是为什么比较两个相同值的引用类型时会为false,比较的其实是他们的引用地址,如图:
这就引出了下一个问题,如图:
相信很多人都知道答案
为什么a会受b影响而c却不会呢?
这是因为a赋值给b时给的是什么?这是因为a赋值的是引用类型栈中的地址,这个地址指向了他们的值,所以地址相同是他们改变的其实是同一个地址上的值。而c赋值给d的是对应栈中的值,所以他们的值放在两个不同的内存空间,任何操作都不会让他们之间有影响。
这也是深拷贝浅拷贝的原理。
null 和 undefined
这两个都表示为空,null是非自然赋值的,undefined是自然赋值的,手动去给变量赋值undefined是不合理的。
obj.key == null,表示这个对象的ke为空值 这是合理的 obj.key == undefined 表示这个对象的key不存在这是没有意义的,
所以undefined表示没有,连这个对应的key也没有 null表示有,但是值为空。
number类型精度丢失的问题
大家有没有遇到过这种类型的面试题 0.1 + 0.2 == 0.3,这么咋一看是不是没什么毛病,但答案是false.
这就是在计算的时候精度丢失的问题,执行加法过程中会将数值转换成二进制进行计算,大多数的小数转成二进制是无限不循环小数,number会取64位的长度来进行表示自然就精度丢失了