2013-10-11 51 views
2
var Counter = (function() { 
    var privateCounter = 0; 
    function changeBy(val) { 
    privateCounter += val; 
    } 
    return { 
    increment: function() { 
     changeBy(1); 
    }, 
    decrement: function() { 
     changeBy(-1); 
    }, 
    value: function() { 
     return privateCounter; 
    } 
    }; 
})(); 

alert(Counter.value()); /* Alerts 0 */ 
Counter.increment(); 
Counter.increment(); 
alert(Counter.value()); /* Alerts 2 */ 
Counter.decrement(); 
alert(Counter.value()); /* Alerts 1 */ 

請問你能解釋一下這行代碼嗎?我明白a ;;方法有一個驢變量計數器共享變量,但它似乎像魔術無論如何因爲我們說它在開始時等於零關閉javascript幫助理解示例

+2

你想了解什麼? – user10

+0

函數是具有屬性和方法的對象。你稱之爲改變它爲「私人」財產的方法。該屬性在初始化時的值爲「0」,但每次調用某個對象方法時都不會給它賦值,只需更改舊對象。 – Zemljoradnik

+0

,如果我沒記錯的話......這不就是在MDN –

回答

1
var Counter = (function() { 

這是創建名爲Counter的對象。它是通過匿名自我調用功能創建的。但是因爲該函數是自調用的,所以不建議使用大寫字母。

var privateCounter = 0; 

正在設置「Private」變量privateCounter。從某種意義上講,它是私人的,您無法直接從外部訪問它。它是在一個匿名函數的範圍內創建的,它賦予它與包含函數的單獨作用域 - Counter。這是您無法從外部訪問的原因,例如Counter.privateCounter === undefined。注意:每當您嘗試從匿名函數訪問this時,結果將爲window對象,但您無法通過window.privateCounter訪問它。

function changeBy(val) { 
    privateCounter += val; 
    } 

這是一個「私人」方法,Counter.changeBy() === undefined。這與var changeBy = function(val){}相同。如果你想使屬性或方法「公開」(從外部訪問),你必須定義它們是這樣的:

this.publicCounter = 0; 
this.changeBy = function(val)... 

這是通常的方式做到這一點,當通過一個未創建你的對象匿名函數(檢查this上述評論),但在這種情況下,你創建它們就像這樣:

return { 
    increment: function() { 
     changeBy(1); 
    }, 
    decrement: function() { 
     changeBy(-1); 
    }, 
    value: function() { 
     return privateCounter; 
    } 
    }; 

這些仍然是Counter「公共」的方法,他們是Counter對象範圍的一部分。您可以像訪問警報一樣訪問它們。

})(); 

這意味着該功能是自行調用的,例如,它正在被立即執行。

現在,我去......當您啓動腳本之前,對象Counter被創建,因爲它是一個自調用函數。這創建了該對象的範圍,並創建了該對象的另一個範圍(具有一個「私有」屬性和一個「私有」方法)。三返回方法是在Counter一個範圍,但它的匿名函數,即使已經回到該函數可以訪問範圍。那是因爲這三種方法都指向了這個範圍,它們裏面仍然有「一些業務」,所以垃圾回收器不會觸及內部變量。匿名函數返回後,您可以訪問其中的值的唯一方法是通過它返回的方法(如果有)。希望這是明確的。現在,我們繼續前進。

alert(Counter.value()); /* Alerts 0 */ 

這要求Counter對象的value()方法。該方法進入已經返回的匿名函數的範圍,並返回本地變量的值。

Counter.increment(); 
Counter.increment(); 

再次,您可以調用對象的「公共」方法,該方法可以訪問已返回的函數中的本地函數。

alert(Counter.value()); /* Alerts 2 */ 

和以前一樣。但請注意,privateCounter處於已返回的函數的範圍內。你不是在創建一個新的,只是通過一些擁有專有權利的方法來訪問舊的。

Counter.decrement(); 
alert(Counter.value()); /* Alerts 1 */ 

如前。

基本上,它就像調用一個勤雜工(對象)和勤雜工總是用他的技能(「公共」的方法和屬性)和工具(「私人」的方法和屬性)。如果你需要做一些事情,請打電話給他,告訴他該做什麼,使用哪種技能,但是如果沒有他,你就不能使用他的工具。而且他有工具收藏,每次給他打電話時都不會買新套。他的鉗子是相同的舊的你踩到,並打破了他最後一次英寸

+0

這是funckin真棒答案謝謝你真的找到了例子)))))))))))))) – user2114177

+0

很高興我的幫助。 :) – Zemljoradnik

+0

*「據我瞭解這是語言的錯誤。」* - 其實,沒有錯誤。'privateCounter'的範圍不是'window',而是匿名函數範圍。如果你將它定義爲'this.privateCounter'而不是'var privateCounter',那麼它就是'window'。 – Carlos

2

JavaScript是全部關於範圍。該代碼在名爲Counter的變量中定義了一個對象,但不是直接。它定義並調用返回對象的函數(使用方法increment()decrement()value())。該對象的範圍是它的創建位置,所以它首先是匿名函數體,然後是de全局名稱空間。儘管閉包沒有被聲明(存儲),並且只被調用一次,但範圍依然存在。以便該對象可以訪問變量privateCounter和方法changeBy()。它是唯一可以訪問這些成員的對象,因此他們被稱爲「私人」。

0

這是很簡單的,我會盡量做到清晰,「counter」是一個對象,它包含三個功能(incrementdecrement和值)和可變(privateCounter) 創建計數器時,該privateCounter是設置爲零作爲一個初始化,這是顯而易見的,但我認爲讓你很難回來三個函數在一起,但認爲它包括他們'計數器',現在每三個函數返回值( value()),或增加/減少一定數量。 現在最後6行應該是有道理的,第一行只是複製初始值爲零,然後我們增加兩次,increment()函數將內部值增加兩倍爲2,並且當您再次執行value()時,它將變爲2,並且decrement()也一樣。我希望我的談話對你有意義。