2012-06-25 29 views
0

更新:2012.06.26 - 請參閱我的結論以下原始問題。在JavaScript中正確的「私人」變量初始化

我想弄清楚爲什麼這個簡單的代碼不能正確初始化。是的,我來自Java世界,我也是一個'純粹主義者',並且想要正確地做JavaScript。

許多(如果不是全部的話)會推薦聲明以'this'爲前綴的變量,從而暴露所有這些變量而不使用適當的setter和getter函數。對我來說這是不可接受的,並不反映良好的面向對象操作。他們說JavaScript是一種OOP語言,那麼爲什麼人們總是試圖繞過這個我永遠不會明白的!?但是,這不是問題,所以讓我們繼續前進......

用下面的代碼的問題是,當我在Chrome中運行它,它不斷告訴我:

Uncaught ReferenceError: x is not defined 

我可以創建一個構造函數,接受默認值,但我寧願不公開默認值假設在那些構造對象的那些上(這也不是好習慣)。另外,在運行期間,setter方法將被調用以更改特定實例的「x」和「y」值。一次有很多'模型'實例!

因此,這裏的簡單代碼:

function Model() { 
    var x = 3; 
    var y = 'hello'; 
} 

Model.prototype.getX = function() { 
    return x; 
} 

Model.prototype.getY = function() { 
    return y; 
} 

Model.prototype.setX = function(myX) { 
    x = myX; 
} 

Model.prototype.setY = function(myY) { 
    y = myY; 
} 

var model = new Model(); 

console.log("Model Y = '" + model.getY() + "'"); 
console.log("Model X = " + model.getX()); 
console.log("Model Y = '" + model.getY() + "'"); 

感謝您的幫助......

結論的問題(更新2012.06.26):

這是很容易得出結論:所要求的(這恰好是如此簡單)不能用JavaScript來完成!

讓我非常驚訝的是,從以下答案可以看出,有些人會認爲,因爲JavaScript不支持它,那麼你不應該使用它或使用它。哇,真是太神奇了!

我已經爭論了很多年,JavaScript不是OOP語言,這個簡單的問題(以及它的答案)可以證明它。

因此,最終它會討論我承認失敗,你和我都需要將我們的代碼更改爲對所有類成員使用「this」關鍵字。語言再一次控制程序員,而不是控制語言的程序員!他們想知道爲什麼2/3以上的軟件項目每年都會失敗!

+3

JavaScript是不是Java。這兩種語言是完全不同的,特別是對象和繼承模型完全不同。 – Pointy

+0

私有變量僅在聲明範圍內以及在該範圍內聲明的方法內可用。 – dqhendricks

+0

顯然,即使Java不能強制執行隱私(http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html)爲什麼要javascript? – Esailija

回答

2
function Model() { 
    var x = 3; 
    var y = 'hello'; 
} 

這會創建一個本地(無用的)變量x,但您希望您新創建的Model實例的屬性。

使用

function Model() { 
    this.x = 3; 
    this.y = 'hello'; 
} 

Model.prototype.setY = function(myY) { 
    y = myY; 
} 

這不會改變你的財產。使用

Model.prototype.setY = function(myY) { 
    this.y = myY; 
} 

是的,javascript和java是非常不同的。更喜歡約定(比如調用以_開頭的私人字段),而不是試圖強制隱私。

+0

正如問題所述,這將暴露變量,OP不想這樣做。 (-1) –

+1

私人財產不是一個很好的做法的JavaScript。 Javascript不是java。 –

+0

同意,但這不回答OP的問題,所以是一個不好的答案。也許你應該發佈的答案是,私人屬性在JavaScript中不是一種有價值的做法。這將回答OP的問題。這不,因此-1。 –

3

一種方法是在Model內定義getXgetY,而不是原型。

function Model() { 
    var x = 3; 
    var y = 'hello'; 
    this.getX = function(){return x;} 
    this.getY = function(){return y;} 
    this.setX = function(val){x=val;} 
    this.setY = function(val){y=val;} 
} 

var foo = new Model(); 
console.log(foo.getX()); 

還有其他方法可以做到這一點,這是我眼中最簡單的方法。

+0

*還有其他的方式*;這是僅支持私有變量的***模式,不是?其缺點是每個'Model'實例都有自己的'getX'和'getY'副本,但這隻在實例化大量'Model'對象時才重要。 – Matt

+1

我這麼認爲。但它增加了功能。 –

+0

@dystroy:的確,但我認爲這種影響*被誇大了,除非你實例化大量的'Model'對象。 – Matt

-2

您將需要使用this

Model.prototype.getX = function() { 
    return this.x; 
} 
+0

我不能說我不期待這個答案! :) – Jeach

+1

爲了記錄,我不是那個降低你的答案的'匿名'懦夫!如果是我,我會讓你知道的。 – Jeach