JS中的作用域有两种:
1.window/global 全局作用域
2.函数执行时形成的私有作用域
栈内存(作用域):js代码执行的那个环境;存储基本数据类型值;
堆内存:在js中,对于引用数据类型来说,首先会开辟一个新的内存空间,然后把("属性名:属性值"/"函数体中的代码字符串")存储到这个空间中,最后把空间的地址给相关的变量,这个新开辟的这个内存空间称之为"堆内存"。堆内存的作用:存储引用数据类型值的
一、全局作用域
在浏览器加载我们HTML页面的时候,首先会开辟一个供js代码执行的环境,即全局作用域,这是一个栈内存
全局变量:在全局作用域下定义的变量
二、私有作用域
函数执行时形成一个新的私有作用域,这也是一个栈内存
私有变量:在私有作用域中经过预解释的变量,形参也是私有变量。
函数执行的顺序:给形参赋值-->预解释-->完成后私有作用域中的代码从上到下执行。
在私有作用域中出现的变量,我们首先看是否为私有变量,如果是私有变量,那么函数中用的都是私有的变量;如果不是私有的变量,则往上一级查找;
关于如何查找上级作用域问题:首先看当前的函数对应的堆内存是在哪个作用域下定义的,在谁下面定义的,它的上级作用域就是谁。
1 var a = 12;
2 function fn() {
3 var a = 13;
4 function f() {
5 console.log(a);
6 }
7 return f;
8 }
9 function sum() {
10 var a = 14;
11 var f = fn();
12 f();//13 f对应的堆内存是在函数fn里面定义的,所以f的上级作用域是fn,所以里面用到的a找的是上级作用域fn中的13
13 }
14 sum();
15 var f=fn();
16 f();//13
关于作用域销毁与不销毁或者不立即销毁问题:
销毁的作用域:
一般情况下,函数执行完成后,浏览器会把这个函数形成的私有作用域进行回收,当前的作用域都立即销毁。
不销毁的作用域:
当函数执行的时候,在私有作用域中返回了一个引用数据类型的值(例如:一个函数、一个对象、一个数组...),并且在函数的外面,有变量接收了这个返回值,此时当前的这个私有的作用域就被占用了,这个作用域也不能销毁了。
作用域不销毁,里面的私有变量也不会被销毁(这跟下一篇要讲的闭包的应用有关)
1 function fn() {
2 var a = 12;
3 return function () {
4 a++;
5 console.log(a);
6 };
7 var c = 13;
8 }
9 var f = fn();
10 f();//13
11 f();//14
不立即销毁的作用域:
当函数执行的时候,在私有作用域中返回了一个引用数据类型的值(例如:一个函数、一个对象、一个数组...),但是并没有变量在函数的外面接收,那么浏览器暂时先不销毁,等到浏览器空闲的时候,会自己销毁这个作用域。