2012-04-08 6 views
2

Ich fragte mich, wie ich private Variablen in JavaScript durch clojure machen konnte. Aber lassen Sie sie immer noch klonen, wenn Sie Object.create verwenden.Javascript private Variablen + Object.create (Verweis auf Closure-Variablen)

var point = {}; 
(function(){ 
    var x, y; 
    x = 0; 
    y = 0; 
Object.defineProperties(point, { 
    "x": { 
     set: function (value) { 
     x = value; 
     }, 
     get: function() { 
     return x; 
     } 
    }, 
    "y": { 
     set: function (value) { 
     y = value; 
     }, 
     get: function() { 
     return y; 
     } 
    } 
    }); 
}()); 

var p1 = Object.create(point); 
p1.x = 100; 
console.log(p1.x); // = 100 
var p2 = Object.create(point); 
p2.x = 200; 
console.log(p2.x); //= 200 
console.log(p1.x); //= 200 

Ich habe diese Technik aus http://ejohn.org/blog/ecmascript-5-objects-and-properties/ aber es hat diese Einschränkung, dass die Schließung Variablen das gleiche für alle Objekte ist. Ich weiß, dass dieses Verhalten auf Javascript angenommen wird, aber wie kann ich echte private Variablen erstellen?

+0

dieser Code sieht automatisch generiert, wurde es von Clojure Code generiert getestet? – Raynos

+0

Nein, es war nicht, warum glaubst du, es sieht automatisch generiert aus? – automaticoo

+0

Als Alternative ohne private Variablen könnte http://jsfiddle.net/heera/G9E9m/ –

Antwort

3

Ich weiß, dass dieses Verhalten auf Javascript angenommen wird, aber wie kann ich echte private Variablen erstellen?

Sie können nicht, es gibt keine private in ES5. Sie können private ES6-Namen verwenden, wenn Sie möchten.

Sie können private ES6-Namen mit ES6 WeakMaps emulieren, die in ES5 eingefügt werden können. Dies ist eine teure und hässliche Emulation, das ist die Kosten nicht wert.

+0

Ich denke, als Alternative ohne private Variablen könnte http://jsfiddle.net/heera/G9E9m/ –

0

Wenn Sie private Variablen nur ein Objekt hinzufügen müssen, die mit Object.create erstellt wurde, kann man das machen:

var parent = { x: 0 } 
var son = Object.create(parent) 
son.init_private = function() 
{ 
    var private = 0; 
    this.print_and_increment_private = function()  
    { 
     print(private++); 
    } 
} 
son.init_private() 
// now we can reach parent.x, son.x, son.print_and_increment_private but not son.private 

Wenn Sie möchten, können auch unnötige öffentliche Funktion init_private wie dies vermeiden:

(function()                                                  
{                                                    
    var private = 0; 
    this.print_and_increment = function() 
    { 
     print(private++); 
    } 
} 
).call(son) 

Schlimme ist, dass man konnte nicht private Mitglieder mit mehreren Anrufen hängen. Das Gute ist, dass diese Methode meiner Meinung nach ziemlich intuitiv ist.

Dieser Code wurde mit 1,7 Rhino Release 01 3 2013 27