闭包--其实很简单

·  阅读 89

在讲闭包之前,我们先来复习一下函数

1.函数的声明

我们知道函数的声明有三种:

1. function f1() {console.log(1)}
2. var f2 = function() {console.log(2)}
3. var f3 = new Function('console.log(3)') //这一种由于很不直观,所以很少使用
复制代码

2.函数的作用域

作用域:

就是这个变量存在的范围,出了这个范围,就没办法找到这个变量了。 如

function f1() {
    var a = 22;
}
console.log(a) //ReferenceError: a is not defined
变量a的作用域在函数f1内部,所以在函数f1外部去读取这个变量是读取不到的
复制代码
js作用域:
1. 全局作用域,在任何地方都可以读取
2. 函数作用域,只在函数体内部可以读取
3. 块级作用域
复制代码

那么,函数本身也是一个值,他也是有作用域的。

划重点: 函数的作用域与变量一样,是函数声明时所在的作用域,跟函数在哪儿运行是没有关系的。

举个例子:

var a = 22;
var f1 = function() {
    console.log(a)
}
function f2 () {
    var a = 33;
    f1();
}
f2() // 22
复制代码

以上代码中,为什么打印出的是22而不是33呢? 因为函数在全局环境声明,作用域是全局,所以去取a的时候,在自己的作用域里面发现没有a,就往上找a,就找到了全局的a

再看个例子:

function f1() {
    var x = 22;
    function f2() {
        console.log(x)
    }
    return f2;
}
var x = 33;
var f3 = f1();
f3() // 22
复制代码

以上代码中,变量x是在函数f1内部的,可是为什么我们在函数外部取到了他的值呢? 那就是因为 我们利用了f2函数。

f2函数是在f1内部声明的,他是可以取到f1内部的变量x的值的,因为我们的作用域链就是一层层往上,

我们将f2函数return 出去之后,再执行他,

他会记住自己的作用域,所以在执行f2函数的时候,他就可以将变量x的值打印出来了。

因此 我们就可以在外部读到这个变量的值了。

以上 函数 f2就是闭包。

闭包,其实就是 可以读取其他函数内部变量的函数。

只有函数内部的子函数才可以读取内部的变量,所以 也可以简单把闭包理解为,“定义在一个函数内部的函数”

分类:
前端