2014-07-02 120 views
0

我遇到了一個閉包問題,我想。我只是做OOP JavaScript的新手(我本週開始......),但是我已經在這裏或那裏使用了JavaScript來處理小DOM操作,並且使用了很多次JQuery魔法。我正在尋找解決我的問題的方法,不涉及更改我的標準,因爲我想嘗試並最終學習正確的JavaScript。我的標準是,我希望解決方案能夠保持我的封裝和Java風格公開訪問的私有變量。我的標準還需要解決方案,以便能夠教我一些關於閉包的知識,而不必在[本頁]重複示例:How do JavaScript closures work?Javascript閉包對象屬性訪問器

我已經在互聯網上尋找解決方案,解決了我的問題和我一直在尋找的視頻,我在學校學習的紅色書籍,我有紅色的網頁和S.O.我經歷過的帖子還沒有向我展示爲什麼會發生這種情況的一個很好的答案。這還是我真的無法把握封閉或什麼這個問題是...

我有這樣一個類:

var Animal = { 
    $name: "Blank", 
    $age: -1, 
    setName: function(n) {this.name=n;}, 
    setAge: function(a) {this.age=a;} 
}; 

要我再後來打電話......

Moose.prototype = Object.create(Animal); 
Moose.prototype.constructor = Moose; 
function Moose(newName, newAge) { 
    this.setName(newName); 
    this.setAge(newAge); 
} 

this.setName()thisthis.setName()做我想要的並且發現動物並且增加一個名字給我的駝鹿而不引起它的駝鹿弟兄們也被稱爲「moosey駝鹿mcDonkeybutt」或者什麼......

我可以成功,然後在控制檯中創建兩個'Meese'或Mooses(如果你願意並且每個都有自己的分隔值)。像...

m1 = new Moose("MooseyMoose", 420); 
m2 - new Moose("MooseMcTingles", 69); 

而且當檢查時m1的值不會與m2相同。這就是我期望從多年來使用的其他語言......但是,這是我感到困惑的地方,或者至少在我的電腦上炫耀,就像,「這是怎麼回事?」

我想添加一些能力來衡量每隻動物如何隨着時間的推移而移動。所以我想,哎,爲什麼不趁這個時候使用真棒力量和對象字面來存儲這些我班裏面....像這樣的簡單....

var Animal = { 
    $name: "Blank", 
    $age: -1, 
    $position: {x:-1,y:-1}, 
    setName: function(n) {this.name=n;}, 
    setAge: function(a) {this.age=a;}, 
    getName: function() { return this.name; } 
}; 

所以我在訪問加有一些額外的負荷......

var Animal = { 
    $name: "Blank", 
    $age: -1, 
    position: {x:-1,y:-1}, //I have tried $ and without 
    setName: function(n) {this.name=n;}, 
    setAge: function(a) {this.age=a;}, 
    getName: function() { return this.name; }, 

    //New Accessor 
    setPosition: function(newX, newY) { 
     this.position.x = newX; 
     this.position.y = newY; 
    } 
}; 

正如我相信有經驗的程序員在這一點讀,說...什麼白癡。問題是我沒有閱讀,搜索或找到答案有我的AHH哈!到下一部分的時刻。如果你已經猜到我會錯誤的,你應該回答。 爲什麼地球上這會導致m1m2現在具有相同的共享值?它不是因爲它公開宣佈我已經嘗試過私人範圍,而且它只是讓this更難找到正確的原型。

我已經試過這麼多的版本的代碼在這個塊試圖找出爲什麼我似乎無法存儲我的立場作爲一個簡單的小對象文字與方便訪問...我需要所有實例的駝鹿( )不能通過使用上面的setPosition()函數來改變彼此的位置....

另外。我曾嘗試將其全部轉換爲function對象而不是var對象,並且我也嘗試刪除很多組合的this,我知道它們沒有達到我需要的範圍,但是沒有運氣。我也嘗試刪除使用.create()方法,並切換到new關鍵字,也沒有運氣。

編輯:對ppl回覆....就像我說過的,我已經嘗試過所有這些,包括將getter setter方法添加到位置變量。它一點也不幫助,它仍然分享價值......

+0

答覆者,請跳過閱讀前三段......這與問題完全無關。 – thefourtheye

+0

在分配給它的原型和其他東西后,看到* Moose *的函數聲明是相當煩人的。如果代碼是按照邏輯順序編寫的,那麼理解它就容易多了。 – RobG

+0

@RobG是的,應該肯定會切換。 – John

回答

2

讓我們一步一步來。

您是否在Moose構造函數中定義了名爲position的成員?

那麼如何Moose對象得到position

通過繼承。由於Moose.prototype被設置爲類型爲Animal的對象,因此當您說m1.position時,JavaScript搜索m1獲得position,並且它在繼承階梯中向上移動以在Moose.prototype對象中找到它。這種搜索對於m1m2都是常見的。因此,他們都在Moose.prototype中找到與Animal相同的對象。可以確認,這樣

console.log(m1.position === m2.position); 
# true 

我們如何解決此得到什麼?

簡單。不要在父對象中定義子對象的成員變量。只需將position的定義移動到Moose構造函數即可。現在,當JavaScript搜索m1.positionm2.position時,它們都將擁有自己的position副本:-)

+0

好的答案。 OP,你可能會發現這個鏈接有助於解釋原型繼承http://javascriptissexy.com/javascript-prototype-in​​-plain-detailed-language/ – drjimmie1976

+0

我知道我可以把它放在駝鹿的構造函數中,但我只是覺得它看起來像來自java和c#的可怕代碼。當它可以屬於從繼承創建的所有東西時重複該變量創建,就好像我重複的東西太多了。 – GoreDefex

+0

換句話說,即使對象生活在被孩子們使用的實例化父對象中,它們也不會被matrer傳遞。我想我不習慣如何JavaScript實例其對象,如動物。 – GoreDefex