每一种语言都会存在内存机制,往往是需要调用内存的时候占用一部分内存空间,当不需要调用的时候自动清除这部分内存(垃圾回收),在JS里也是这样,只是在某些时候,JS解析器(解释分析并运行JS代码的东西)不知道什么时候可以回收该内存(闭包就是这样,在后续会讲)。而且JS里的基本数据类型和引用数据类型占用内存的方法也不一样哦,下面就一一分析:
1基本数据类型只用栈内存
<script>
var a=10;
</script>
当JS解释器在运行到这个代码时,会做两件事,一是先声明一个变量a,然后再给这个变量a赋值为数字10
那么在内存里这个过程是怎么实现的呢?
首先,会在栈内存(可以想象成堆叠起来的方块)里开辟一块给这个变量,然后直接在当前栈内存里给这个变量赋值数字10,不管赋值的是数字还是字符串,只要属于基本数据类型,都会占用栈内存空间,当多个变量值相等时,改变一个变量值,其余的变量不会发生改变,因为只是变量的值发生了改变。
2
引用数据类型同时使用栈内存和堆内存
<script>
var a=new Array() //数组的构造器写法
</script>
当JS解释器在运行到这个代码时,会做两件事,一是先声明一个变量a,然后再给这个变量a赋值为一个空数组
那么在内存里这个过程是怎么实现的呢?
首先,会在栈内存(可以想象成堆叠起来的方块)里开辟一块给这个变量,然后在堆内存(可以想象成无序排列的圆圈)里给这个数组开辟一个空间,接着栈内存里的变量会被赋值成堆内存的内存地址(一个指针,指向堆内存空间的挂钩,且唯一),所以引用数据类型同时使用了栈内存和堆内存,当多个变量都赋值为同一个数组(或者是对象)时,改变一个变量的属性,其余的变量的属性会发生改变,因为都指向一个堆内存,所以相当于直接对数组进行了操作。
可能这样写大家还是一脸懵逼,没事,咋们举个例子:
<script>
var a=10,b=a /*如果多个变量声明只写一个var关键字,需要将声明写在同一行,以逗号隔开*/
</script>
如果a=20;
b==a?,答案是肯定不等于,因为b当前的栈内存里面赋值的是数字10,只是a的栈内存赋值被改变成了20,相互不会影响。
再举一个例子:
<script>
var a=[1,2,3] //数组的字面量写法
var b=a /*相当于b的栈内存里面赋值了a一样的内存地址,都指向同一个数组*/
a[3]=4; /*给数组增加一个值,值为4,数组会在后续讲*/
</script>
b==a?,答案是相等的,我们可以打印下此时的b,console.log(b)。会在浏览器控制台打印出[1,2,3,4],为什么会这样呢?因为a的操作运用了数组的方法,相当于堆内存里的数组自身发生了变化,而栈内存里a和b的地址并没有发生改变
再举一个不同的例子:
<script>
var a=[1,2,3] //数组的字面量写法
var b=a //相当于b的栈内存里面赋值了a一样的内存地址,都指向同一个数组
a=[]; //给a重新赋值了一个空数组,改变了a栈内存的内存地址
</script>
这个时候a==b?肯定是不等的,因为这个时候,内存空间被会重新划分,栈内存里,a赋值为空数组的内存地址,b还是之前数组的内存地址,此时堆内存里面会有两个堆,一个是之前的数组,另一个是空数组。
最后给大家上一张图,可能会更好理解,不同数据类型的内存机制大家一定要好好理解,对后面的学习很重要。
JS里面不同变量和数据之间经常会用到运算符
1
一个等号=
JS里面一个等号可不是数学里的等于,而是赋值的意思,就是将等号后面的赋值给等号前面的
2
两个等号==和其余的数学运算符
两个等号才是数学里面的相等,可以比较==前后的值是否相等,数学里面的加减乘除在JS里也适用
只是这里有两个坑:
3
逻辑运算符和比较运算符
逻辑与&& 只有当前后两个都为真,才会得到true
逻辑或 || 前后只要有一个为真,都会得到true
逻辑非! 将值取反,如果值为true,取反得到false !=是不等于,不是逻辑运算符
逻辑运算符和两个等号一般用于判断,因为得到的值都是布尔值true或者false
4
位移运算符(用的相当少)
>>,<<,~ 这三个属于位于运算符,前两个是将值先转换成二进制,然后位移小数点再转换回十进制,最后一个也需要转换进制,取反码。这里只做了解,用的非常少
5
逗号运算符和函数运算符
(逗号用的也很少,面试可能会遇到,坑)
JS里面单独的逗号也属于运算符,意思是从左往右计算,会返回最后一个值
比如:
<script>
var a=(1,2,3) //最终a会赋值成3
</script>
函数运算符主要是指函数调用会用一堆圆括号();
比如:alert();这里是调用的window对象的方法
好了,讲了这么多运算符,那么它们之间有没有先后顺序呢?Bingo,运算符是有优先级的,目前Alan所了解的运算符里优先级顺序是:
数学运算符>逻辑运算符>赋值运算符>函数运算符>逗号运算符
举个例子:
<script>
alert(3+5>5) //会弹出true
//这里有一个坑哦
alert(1,2,3) //会弹出1而不是3,因为函数运算符优先级比逗号运算符高
alert((1,2,3)) /*如果像让逗号运算符先运算,只需在外面加一个圆括号,圆括号会使优先级提高*/
</script>