2014-02-26 80 views
1

我在Mozilla開發者頁面中找到了這個例子,但是無法理解這個概念。外部函數如何「存儲」內部函數的參數?

function outside(x) { 
     function inside(y) { 
      return x + y; 
     } 
     return inside; 
    } 
    fn_inside = outside(3); //returns inside(y) -- from firebug 
    result = fn_inside(5); // returns 8 

    result1 = outside(3)(5); // returns 8 

好像3稍微存儲在函數「inside」和第二呼叫期間與5將它和返回8.

以及如何做到外部的第二呼叫(outside(3)(5))返回值(8)而不是第一次調用內部函數(inside)?

+1

@elclanrs也許吧。但我甚至不知道OP在這裏有什麼問題......它可能是*「函數如何存儲在變量中?」或*「變量如何工作?」...... –

回答

2

好像3有些存儲在「裏面」的第二呼叫過程中的作用與5增加了它,並返回8

權。每個呼叫outside創建一個新的inside函數,並且該函數具有綁定到它的呼叫到outside的數據。它「關閉」了這些數據。這些被稱爲「封閉」。不要讓名字打擾你,closures are not complicated

第二次調用outside(outside(3)(5))如何返回值(8)而不是第一次調用的內部函數(內部)?

第二次調用outside確實返回一個功能(由該調用生成的inside功能);但是隨後你會立即用第二對()調用該函數。

outside(3)(5); 

...打破了這樣的:

var f = outside(3); // Create and get the `inside` function bound to 3 
f(5);    // Call it, passing in `5` 

從您的評論:

那麼你的意思是,在第一致電outside(3),'返回'inside方法od定義變成(改爲?)返回3 + y;。是對的嗎?

關閉,但不完全。 x的值不會被燒入inside; inside有創建它的上下文的引用,並且該上下文使它可以訪問x參數。這些都是不太一樣的東西,因爲我們可以看到,如果我們更新了示例位(與溝的數學,這只是掩蓋的東西):

function outside(name) { 
    // 'inside' uses the 'name' argument from the call to 'outside' that created it 
    function inside() { 
     return name; 
    } 

    // 'changer' *changes* the 'name' argument's value 
    function makeCaps() { 
     name = name.toUpperCase(); 
    } 

    // Return both of them 
    return { 
     inside: inside, 
     makeCaps: makeCaps 
    }; 
} 

var funcs = outside("foo"); 
funcs.inside();  // "foo", because 'inside' uses the 'name' created 
        // by the call to 'outside', and that 'name' is 
        // currently "foo" 
funcs.makeCaps(); // Changes that same 'name' 
funcs.inside();  // "FOO", because that 'name' has been changed 

這是關鍵要了解這兩個insidechanger關過相同上下文,這是創建它們的調用outside的上下文。

這也是關鍵要明白,一個新的環境和新的功能是由每個調用創建outside

var funcs1 = outside("foo"); 
var funcs2 = outside("separate"); 
funcs1.inside();  // "foo" 
funcs2.inside();  // "separate" 
funcs1.makeCaps(); 
funcs1.inside();  // "FOO" 
funcs2.inside();  // "separate" 
+0

感謝Crowder。現在有點清楚了。那麼你的意思是,在第一次調用'outside(3)'的時候,方法定義中的'returned'變成(改成?)'return 3 + y;'。是對的嗎? – Bere

+0

@Bere:關閉,但不完全;我在上面添加了進一步的解釋。 –

+0

我幾乎瞭解這個概念。最後一個問題:我認爲之後例如outer(「foo」)被調用,它已經消失,它的內存被回收...,沒有它的痕跡 - 除了返回的值。但從你的答案我明白,通過保持其內在功能,我們實際上可以保留外部函數的「上下文」(變量...)。可以? – Bere

0

你的變量「X」是在外面作用的範圍,以及你的內部功能。所以當你調用外部函數時,它會在裏面創建新的函數,並且存儲變量X,然後,當執行函數內部函數時,你已經有了X,並且從它的參數中獲取Y.

相關問題