鍍金池/ 問答/HTML/ js閉包的問題

js閉包的問題

<!doctype html>
<html>

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

    <!-- 但是在外部是無法獲取方法內(nèi)部的局部變量的 -->
    function func2(){
        var num1 = 22;
        num2 = 33;
    }
    func2();
    <!--console.log(num1);  會報錯!-->
    console.log(num2); <!--可以獲取到num2的值,因為不適用var定義變量時,默認(rèn)是全局變量 -->

    <!-- 那么如何在外部獲取到內(nèi)部的變量呢!javascript可以辦到 -->
    function func3(){
        var num3 = 44;
        function func4(){
            return num3;
        }
        return func4;
    }
    var func = func3();
    console.log(func());

    </script>
</body>

</html>

第三個中...為什么不直接return num3呢。。。
在外面包一個func4有什么區(qū)別。。。。。。不都是返回num3嗎。。求大神解惑。。這各問題把我弄蒙了

回答
編輯回答
淡墨

1、如果你所有的變量都定義在最外層,也就是window環(huán)境下,你要想一想,如果程序變得越來越大,你一個不小心就把某一個變量修改了,bug很難定位
2、閉包簡單來說,就是內(nèi)層函數(shù)能夠訪問到作用域鏈上的變量。你的例子太簡單了,如果單單只返回值,怎么返回都沒什么區(qū)別,但是如果你是暴露接口方法,使之能操作你函數(shù)里面的變量呢?這就又不一樣了,只返回值你永遠(yuǎn)不能在外層對這個變量進(jìn)行修改,相當(dāng)于把你的變量封裝了起來,外層不能改變他,也就解決了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()

這樣是不是就封裝了一些操作了,也變得更加有意義呢?例子還是太簡單,只是說明對變量的封裝。

2018年6月13日 04:16
編輯回答
瞄小懶

關(guān)于閉包主要記住以下兩點

  1. ES5中只有函數(shù)作用域,在當(dāng)前函數(shù)里找不到變量時會逐級向上查找,直到全局(window)

  2. 當(dāng)把函數(shù)被當(dāng)做參數(shù)來傳遞時就會產(chǎn)生閉包,連同函數(shù)可訪問的作用域一起傳遞(也就是閉包)

分析一下你的第三個例子
在func3外面本來是不能訪問到內(nèi)部變量num3的
但是func4是可以的,因為他在func3內(nèi)部,根據(jù)上面第1條,是可以訪問num3。

由于func4被func3返回并傳給了func,所以func就具備了func4的可訪問的作用域,自然就可以訪問到num3
如果你還是不明白,推薦看一下《你不知道的JavaScript》上卷,閉包那一章講得很清楚

2018年8月27日 20:22
編輯回答
薄荷糖

首先你要明白,javascript在使用變量時是逐層往上找的,這就導(dǎo)致了外面無法訪問里面的變量,那么這里有一個垃圾回收機制,當(dāng)一個變量沒有任何引用的時候,這個變量就會被回收。

ok,看第三個例子,其實他想表達(dá)的意思是,num3這個變量被func4使用著,而func4被返回給了func,這樣num3這個變量就不會被回收,也就從外面拿到了里面的變量。至于你說的直接返回return num3.這樣相當(dāng)于是直接返回了一個變量,那我還不如直接返回一個具體的值嘞~
表達(dá)能力不行,見諒

2018年8月11日 18:15