2010-03-02 7 views
12

Ich möchte die Struktur eines Objekts unveränderlich machen und verhindern, dass seine Eigenschaften später ersetzt werden. Die Eigenschaften müssen jedoch lesbar sein. Ist das möglich?Gibt es eine Möglichkeit, den Austausch von JavaScript-Objekteigenschaften zu verhindern?

Ich bin sicher, es gibt keine Sprachfunktionen (in final in Java und readonly in C#), um dies zu unterstützen, aber gefragt, ob es einen anderen Mechanismus für das gleiche Ergebnis geben könnte?

Ich suche nach etwas in diese Richtung:

var o = { 
    a: "a", 
    f: function() { 
     return "b"; 
    } 
}; 

var p = o.a;  // OK 
o.a = "b";   // Error 
var q = o.f();  // OK 
o.f = function() { // Error 
    return "c"; 
}; 

Antwort

14

ECMAScript 5 wird seal() und freeze() haben, aber es gibt keine gute Möglichkeit, dies mit aktuellen JavaScript-Implementierungen zu tun.

Source.

+1

+1: ' freeze() 'klingt nach dem, wonach ich suche. –

+0

Sie haben Version 5? – mkoryak

+1

Ich erwähnte es nur als Referenz. Ich programmiere nicht aktiv gegen ECMAScript 5. – EndangeredMassa

9

das Beste, was Sie Ihre Eigenschaften innerhalb eines Verschlusses verstecken tun können.

var getMap = function(){ 
    var hidden = "1"; 
    return { 
    getHidden : function() { return hidden; } 
    } 
} 

var f = getMap(); 

alert(f.getHidden()); 

Ich habe einen Stich gemacht. In dem obigen Code müssen Sie nicht nur verborgen zurückgeben, sondern es vielleicht in ein neues Objekt kopieren. Vielleicht können Sie die Erweiterung von jquery verwenden, um dies für Sie zu tun, sodass Sie ein neues Objekt und nicht die Referenz zurückgeben. Dies kann jedoch völlig falsch sein =)

+0

bis 99 gesperrt ist jetzt muss ich die Eigenschaften von außerhalb des Objekts zugänglich sein (Frage aktualisiert, um) . –

+0

@Matthew So erstellen Sie eine öffentliche Zugriffsfunktion. Siehe meine Antwort. –

+0

editierte Antwort zu sein wie, was Sie wollen – mkoryak

4

Wie mkoryak sagte, können Sie einen Verschluss erstellen, um Eigenschaften zu verbergen

function Car(make, model, color) { 
    var _make = make, _model = model, _color = color; 

    this.getMake = function() { 
     return _make; 
    } 

} 

var mycar = new Car("ford", "mustang", "black"); 

mycar.getMake(); //returns "ford" 
mycar._make; //error 
+0

Wenn mkoryak das schon gesagt hat, warum wiederholen Sie es? – Zecc

+1

@Zecc, weil diese Antwort ursprünglich kein Code-Beispiel hatte –

5

var in einem Objekt-Konstruktor wird eine private Variable erstellen. Dies ist im Wesentlichen eine Schließung. Dann können Sie eine öffentliche Funktion erstellen, um auf sie zuzugreifen/sie zu ändern. Weitere Informationen und Beispiele finden Sie unter Private Members in Javascript von Douglas Crockford.

+1

Aber dann können Sie die Funktion ersetzen, um zurückzugeben, was auch immer Sie wollen. – EndangeredMassa

+0

@Sean Sicher kann es gelöscht/ersetzt werden, aber es kann nicht geändert werden. Ich denke, die Quintessenz ist, dass es keine Möglichkeit gibt, die Funktion durch etwas zu ersetzen, das direkten Zugriff auf die private Variable geben würde. –

4

Okay, also gibt es bereits ein paar Antworten, die darauf hindeuten, dass Sie ein Objekt mit mehreren Getter-Methoden zurückgeben. Aber Sie können diese Methoden immer noch ersetzen.

Da ist das, was etwas besser ist. Sie können die Eigenschaften des Objekts nicht ersetzen, ohne die Funktion vollständig zu ersetzen. Aber es ist immer noch nicht genau das, was du willst.

2

Sie können jetzt erzwingen, dass eine einzelne Objekteigenschaft eingefroren wird, anstatt das gesamte Objekt einzufrieren. Sie können diese writable: false

var obj = { 
    "first": 1, 
    "second": 2, 
    "third": 3 
}; 
Object.defineProperty(obj, "first", { 
    writable: false, 
    value: 99 
}); 

In diesem Beispiel mit Object.defineProperty und den Parameter erreichen, obj.first seinen Wert