2014-01-21 147 views
0

你好,我已經開始學習一些JavaScript,我無法用「正常」函數來包裹我的頭。我不明白爲什麼以下兩個函數輸出不同的結果。 f2輸出5,而f1輸出1.爲什麼?Javascript模塊模式和函數調用

var f1 = function(){ 
    var x= 1; 

    var add = function(){ 
    x=5; 
    }; 

    var result = function(){ 
    console.log(x); 
    }; 

    return { 
    add: add, 
    result: result 
    }; 
}; 

f1().add(); 
f1().result(); 

var f2= (function(){ 
    var x= 1; 

    var add = function(){ 
    x=5; 
    }; 

    var result = function(){ 
    console.log(x); 
    }; 

    return { 
    add: add, 
    result: result 
    }; 
})(); 

f2.add(); 
f2.result(); 
+1

您使用的是相同的'x'全局變量,因爲你沒有用'var'聲明它是這樣做的目的? – elclanrs

+0

對不起,我忘了。我加了var,但是f1仍然輸出1. – user1870482

+0

這裏沒有* this *。 :-) – RobG

回答

1

第一個示例顯示了兩個調用f1()

  • f1()第一調用創建一個新的可變範圍相x設置爲1,並且返回與該方法的對象。 .add()然後將該x設置爲5

  • f1()的第二次調用創建另一個新變量作用域,其中x再次設置爲1,並返回帶有方法的對象。然後.result()返回x,它仍然是1


第二個示例僅調用f2()一次,所以有與正在創建x和新方法沒有新的可變範圍。


所以基本上f1的兩個調用初始化x每次調用,並與方法返回兩個不同的對象更接近在兩個不同的x變量。

f2被調用一次,因此有一個x變量與返回的方法共享一個對象。因此,.add()呼叫和.result()呼叫正在使用相同的x變量。

+0

差不多。第一個不需要兩個調用。如果他將執行f1並將結果保存在一個變量中,然後執行這些方法,bot f1和f2將返回相同的結果 – Kenneth

+0

@Kenneth:是的,按「requires」我的意思是這個例子顯示了兩個單獨的調用。也許這不是最好的用詞。 –

+0

好的,我必須在哪裏將結果保存在變量中? – user1870482

1

讓我勾勒出你的代碼會發生什麼:

// Declares a function named f1. 
var f1 = function() { 
    // Searches each scope (the scope of f1, the scope containing f1, etc.) for 
    // a variable named x. If found, it will reassign it to 1. If the search reaches 
    // the global scope and no variable is found it will declare and initialize 
    // a global variable. 
    x = 1; 

    // Declares a local variable named add to a function that reassigns the value of x. 
    var add = function() { 
    x = 5; 
    }; 

    // Declares a local variable named result to a function that logs the value of x. 
    var result = function() { 
    console.log(x); 
    }; 

    // Returns an object containing each function. 
    return { 
    add: add, 
    result: result 
    }; 
}; 

// Calls f1 and the returned add function. 
f1().add(); 

// Calls f1 again (which reassigns x) and calls the returned result function. 
f1().result(); 


// Creates a variable named f2 and assigns to the result of applying an anonymous 
// function. f2 now references the returned object. 
var f2 = (function() { 
    // Reassigns x, does not create a new variable. 
    x = 1; 

    var add = function() { 
    x = 5; 
    }; 

    var result = function() { 
    console.log(x); 
    }; 

    return { 
    add: add, 
    result: result 
    }; 
})(); 

// The difference now is that the function that contains add and result is only 
// called once, during the initialization of f2. Had you written var g = f1(); 
// g.add(); g.result(); you would have gotten the exact same results. 
f2.add(); 
f2.result(); 
+0

感謝您的詳細解釋。我是對的,返回的對象只包含對函數的引用? – user1870482

+0

@ user1870482是的,當你調用f1時,你返回了兩個完全不同的引用(或對象),並調用add,然後導致另一個。當你調用f2時,你使用相同的引用來調用add和result。 –