再说闭包

已经记不清是哪个本书的哪个作者说过, 如果你不能把一个问题给6岁的孩子讲明白,那么你自己其实也还是没有明白

闭包这个概念其实已经被提及很多年了,java8是否支持闭包当初在csdn上也争论了许久(结果它弄了一个Lambda)

即便是现在出去找工作也经常会被问到, 什么是闭包 ( 相信我,我做面试官的时候从来没问过这个问题 )

今天觉得有必要重新整理一下关于闭包的知识

1 作用域

2 作用域

3 作用域

重要的事情说三遍

这里我们还是先以javascript为例

对变量作用域的控制 是javascript语言 实现闭包的必要手段

所谓的闭包, 在javascript中就是在函数B中(作用域B), 能够访问到函数A(作用域A)的变量

强调一下javascript只有全局变量(不带var),和局部变量(带var)

假设我们有函数A和函数B

function A(){

var test = 1;

}

function B(){

}

那么如何能使用函数B访问到函数A中的局部变量test呢 ( 当然了,如果你使用全局变量或者参数传递我们就不用在这啰嗦闭包了)

在javascript中, 只有一个函数内部的子函数,能访问这个函数的局部变量

接下来我们把这个函数修改一下,让函数B成为函数A的一部分

function A(){

    var test = 1;

    function B(){

        test = test+1;

        alert(test);

    }

}

现在我们可以说, 这段代码是闭包了么, 是,但是也不完全是, 现在的问题是, 我们只是有一个函数和它的子函数,如何直接通过子函数(function B)来访问到主函数的局部变量(test)是眼前的问题,手段其实挺多的

1 你可以声明一个全局变量,然后指向函数B,这样你就可以在函数A的外部通过这个变量调用函数B

2 你还可以让函数A返回B,然后赋给一个全局变量

3 最后你还可以选择把函数B当参数传出来

第一种方式

<html>

<head>

<script type="text/javascript">

var global;

function A(){
    
    var test = 1;
    
    function B(){
        test = test+1;
        alert(test);
    }
    
    global = B;
}

function run(){
    global();
}

A();

</script>

</head>

<body>

<input type="button" value="run" onclick="run()"/>

<div id="plane">

</div>

</body>

</html>

第二种方式(网上这种例子比较多哈)

<html>

<head>

<script type="text/javascript">

function A(){
    
    var test = 1;
    
    function B(){
        test = test+1;
        alert(test);
    }
    
    return B;
}

function run(){
    global();
}

var global = A();

</script>

</head>

<body>

<input type="button" value="run" onclick="run()"/>

<div id="plane">

</div>

</body>

</html>

第三种方式(感觉是写起来最麻烦而且完全没必要,这里就是为了折腾一下)

<html>

<head>

<script type="text/javascript">

var global;

function A(){
    
    if(test==undefined){
        var test = 1;
    }
    
    
    function B(){
        test = test+1;
        alert(test);
    }
    
    transfer(B);
}

function transfer(fn){
    global=fn;
}

function run(){
    global();
}

A();

</script>

</head>

<body>

<input type="button" value="run" onclick="run()"/>

<div id="plane">

</div>

</body>

</html>