闭包

作为js的三座大山之一的闭包。
闭包原理:函数作用域,垃圾回收机制,作用域链
一个一个来

函数作用域是什么呢?

首先,js的作用域分为函数作用域和静态作用域
静态作用域指的是一段代码,在它执行之前就已经确定了它的作用域,简单来说就是在执行之前就确定了它可以应用哪些地方的作用域(变量)。
动态作用域–函数的作用域是在函数调用的时候才决定的

  1. 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
  2. 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
  3. 在函数作用域中可以访问到全局作用域的变量
  4. 在全局作用域中无法访问到函数作用域的变量
  5. 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
    如果没有则向上一级作用域中寻找,直到找到全局作用域,
    如果全局作用域中依然没有找到,则会报错ReferenceError
  6. 在函数中要访问全局变量可以使用window对象
var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2;
    foo();
}
bar();
// 结果是 1

假设JavaScript采用静态作用域,让我们分析下执行过程:
执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

假设JavaScript采用动态作用域,让我们分析下执行过程:
执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。

前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1。
看到这里我们就可以看出闭包是使用动态作用域的。

为什么闭包使用动态作用域的呢

JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效。

下面的例子是结合上了立即执行函数

function create(){
    var result=new Array()
    for(var i=0;i<10;i++){
        result[i]=function(num){
            return function (){return num}()
        }(i)
    }
    return result
}
console.log(create())  // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
插播:执行上下文是什么?
18774841-2035b8283635bbcc.png
图片.png

执行上下文包括了变量对象,作用域,this指针


18774841-80aa127cc214b7a6.png
599584-c850e91b12e88831.png

最后再来顺一遍,js代码编译执行过程吧
一个js文件,首先编译器先进行编译,把它转化为可执行代码
这个过程编译器做了什么工作呢?(如上图)

闭包其他的原理之前已经写过啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值