js闭包的问题

<!doctype html>
<html>

<head>
</head>
<body>
    <script type="text/javascript">
    <!-- 在正常的脚本中,某个方法可以获取到外部的变量,或者全局变量 -->
    var num = 11;
    function func1(){
        console.log(num);
    }
    func1();

    <!-- 但是在外部是无法获取方法内部的局部变量的 -->
    function func2(){
        var num1 = 22;
        num2 = 33;
    }
    func2();
    <!--console.log(num1);  会报错!-->
    console.log(num2); <!--可以获取到num2的值,因为不适用var定义变量时,默认是全局变量 -->

    <!-- 那么如何在外部获取到内部的变量呢!javascript可以办到 -->
    function func3(){
        var num3 = 44;
        function func4(){
            return num3;
        }
        return func4;
    }
    var func = func3();
    console.log(func());

    </script>
</body>

</html>

第三个中...为什么不直接return num3呢。。。
在外面包一个func4有什么区别。。。。。。不都是返回num3吗。。求大神解惑。。这各问题把我弄蒙了

阅读 2.1k
3 个回答

1、如果你所有的变量都定义在最外层,也就是window环境下,你要想一想,如果程序变得越来越大,你一个不小心就把某一个变量修改了,bug很难定位
2、闭包简单来说,就是内层函数能够访问到作用域链上的变量。你的例子太简单了,如果单单只返回值,怎么返回都没什么区别,但是如果你是暴露接口方法,使之能操作你函数里面的变量呢?这就又不一样了,只返回值你永远不能在外层对这个变量进行修改,相当于把你的变量封装了起来,外层不能改变他,也就解决了1里的问题
3、如2中所说,你可以

function func3 () {
    var num = 1
    function add () {
        num++
    }
    function getNum () {
        return num
    }
    return {
        add: add,
        getNum: getNum
    }
}
var t = func3()
t.add()
t.getNum()

这样是不是就封装了一些操作了,也变得更加有意义呢?例子还是太简单,只是说明对变量的封装。

首先你要明白,javascript在使用变量时是逐层往上找的,这就导致了外面无法访问里面的变量,那么这里有一个垃圾回收机制,当一个变量没有任何引用的时候,这个变量就会被回收。

ok,看第三个例子,其实他想表达的意思是,num3这个变量被func4使用着,而func4被返回给了func,这样num3这个变量就不会被回收,也就从外面拿到了里面的变量。至于你说的直接返回return num3.这样相当于是直接返回了一个变量,那我还不如直接返回一个具体的值嘞~
表达能力不行,见谅

关于闭包主要记住以下两点

  1. ES5中只有函数作用域,在当前函数里找不到变量时会逐级向上查找,直到全局(window)

  2. 当把函数被当做参数来传递时就会产生闭包,连同函数可访问的作用域一起传递(也就是闭包)

分析一下你的第三个例子
在func3外面本来是不能访问到内部变量num3的
但是func4是可以的,因为他在func3内部,根据上面第1条,是可以访问num3。

由于func4被func3返回并传给了func,所以func就具备了func4的可访问的作用域,自然就可以访问到num3
如果你还是不明白,推荐看一下《你不知道的JavaScript》上卷,闭包那一章讲得很清楚

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题