# 导读
变量和类型是学习JavaScript最先接触到的东西,但是往往看起来最简单的东西往往还隐藏着很多你不了解、或者容易犯错的知识,比如下面几个问题:
JavaScript中的变量在内存中的具体存储形式是什么?0.1+0.2为什么不等于0.3?发生小数计算错误的具体原因是什么?Symbol的特点,以及实际应用场景是什么?[] == ![]、[undefined] == false为什么等于true?代码中何时会发生隐式类型转换?转换的规则是什么?- 如何精确的判断变量的类型?
如果你还不能很好的解答上面的问题,那说明你还没有完全掌握这部分的知识,那么请好好阅读下面的文章吧。
本文从底层原理到实际应用详细介绍了JavaScript中的变量和类型相关知识。
# 一、JavaScript数据类型
ECMAScript标准规定了7种数据类型,其把这7种数据类型又分为两种:原始类型和对象类型。
原始类型
Null:只包含一个值:nullUndefined:只包含一个值:undefinedBoolean:包含两个值:true和falseNumber:整数或浮点数,还有一些特殊值(-Infinity、+Infinity、NaN)String:一串表示文本值的字符序列Symbol:一种实例是唯一且不可改变的数据类型
(在es10中加入了第七种原始类型BigInt,现已被最新Chrome支持)
对象类型
Object:自己分一类丝毫不过分,除了常用的Object,Array、Function等都属于特殊的对象
# 二、为什么区分原始类型和对象类型
# 2.1 不可变性
上面所提到的原始类型,在ECMAScript标准中,它们被定义为primitive values,即原始值,代表值本身是不可被改变的。
以字符串为例,我们在调用操作字符串的方法时,没有任何方法是可以直接改变字符串的:
var str = 'ConardLi';
str.slice(1);
str.substr(1);
str.trim(1);
str.toLowerCase(1);
str[0] = 1;
console.log(str); // ConardLi
@前端进阶之旅: 代码已经复制到剪贴板
在上面的代码中我们对str调用了几个方法,无一例外,这些方法都在原字符串的基础上产生了一个新字符串,而非直接去改变str,这就印证了字符串的不可变性。
那么,当我们继续调用下面的代码:
str += '6'
console.log(str); // ConardLi6
@前端进阶之旅: 代码已经复制到剪贴板
你会发现,str的值被改变了,这不就打脸了字符串的不可变性么?其实不然,我们从内存上来理解:
在JavaScript中,每一个变量在内存中都需要一个空间来存储。
内存空间又被分为两种,栈内存与堆内存。
栈内存:
- 存储的值大小固定
- 空间较小
- 可以直接操作其保存的变量,运行效率高
- 由系统自动分配存储空间
JavaScript中的原始类型的值被直接存储在栈中,在变量定义时,栈就为其分配好了内存空间。
