BEARBEITEN Okt. 2016 : Bitte beachten Sie, dass diese Frage im Jahr 2012 gestellt wurde. Jeden Monat fügt jemand eine neue Antwort oder einen neuen Kommentar hinzu, der eine Antwort widerlegt, aber dies ist nicht wirklich sinnvoll, da die Frage wahrscheinlich veraltet ist (denken Sie daran, Es war Sache von Gnome Javascript , Gnome-Shell-Erweiterungen zu schreiben, keine Browser-Inhalte (was ziemlich spezifisch ist).
Nach meiner vorherigen Frage zur Durchführung von Unterklassen in Javascript erstelle ich eine Unterklasse aus einer Oberklasse wie folgt:
function inherits(Child,Parent) {
var Tmp = function {};
Tmp.prototype = Parent.prototype;
Child.prototype = new Tmp();
Child.prototype.constructor = Child;
}
/* Define subclass */
function Subclass() {
Superclass.apply(this,arguments);
/* other initialisation */
}
/* Set up inheritance */
inherits(Subclass,Superclass);
/* Add other methods */
Subclass.prototype.method1 = function ... // and so on.
Meine Frage ist, wie definiere ich mit dieser Syntax einen Setter / Getter auf dem Prototyp?
Früher habe ich gemacht:
Subclass.prototype = {
__proto__: Superclass.prototype,
/* other methods here ... */
get myProperty() {
// code.
}
}
Aber offensichtlich funktioniert Folgendes nicht:
Subclass.prototype.get myProperty() { /* code */ }
Ich verwende GJS (GNOME Javascript) und die Engine soll mehr oder weniger mit der von Mozilla Spidermonkey identisch sein. Mein Code ist nicht für einen Browser gedacht, solange er von GJS unterstützt wird (ich denke, das bedeutet Spidermonkey?), Es macht mir nichts aus, wenn er nicht kreuzkompatibel ist.
quelle
__defineGetter__
und__defineSetter
(aber ich habe diese nie benutzt ...). developer.mozilla.org/en/Core_JavaScript_1.5_Guide/…Antworten:
Verwenden einer Objektliteraldeklaration (einfachster Weg):
var o = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2 } };
Verwenden
Object.defineProperty
(in modernen Browsern, die ES5 unterstützen):Object.defineProperty(o, "myProperty", { get: function myProperty() { // code } });
Oder mit
__defineGetter__
und__defineSetter__
( DEPRECATED ):var d = Date.prototype; d.__defineGetter__("year", function() { return this.getFullYear(); }); d.__defineSetter__("year", function(y) { this.setFullYear(y); });
quelle
let foo = { bar () { return baz }}
get
/set
Syntax scheint die neue Methodensyntax inspiriert zu haben :)this
in Lambdas bezieht sich auf globales Objekt.Verwenden Sie
Object.defineProperty()
aufSubclass.prototype
. Es gibt auch__defineGetter__
und__defineSetter__
in einigen Browsern verfügbar, aber sie sind veraltet. Für Ihr Beispiel wäre es:Object.defineProperty(Subclass.prototype, "myProperty", { get: function myProperty() { // code } });
quelle
__proto__
)" - beachten Sie, dass ab__proto__
dem ES6-Entwurf standardisiert wird.Object.create
stattdessen zu verwenden .Object.defineProperty(…, "duration", { get: function() { return this.end - this.begin; }});
Ich denke, Sie wollten so vorgehen:
function Unit() { this._data; // just temp value } Unit.prototype = { get accreation() { return this._data; }, set accreation(value) { this._data = value }, } Unit.prototype.edit = function(data) { this.accreation = data; // setting this.out(); }; Unit.prototype.out = function() { alert(this.accreation); // getting }; var unit = new Unit(); unit.edit('setting and getting'); function Field() { // children } Field.prototype = Object.create(Unit.prototype); Field.prototype.add = function(data) { this.accreation = data; // setting this.out(); } var field1 = new Field(); field1.add('new value for getter&setter'); var field2 = new Field(); field2.out();// because field2 object has no setting
quelle
Object.defineProperty
keinen Grund zur Verwendung, es sei denn, Sie müssen die Beleidigung des alten IE erleiden.Object.defineProperty()
anstelle des obigen Beispiels zu verwenden, wenn Sie aufzählbar, konfigurierbar, beschreibbar usw. festlegen möchten. Aber Sie haben Recht, ein Blick auf das Datum des Beitrags ist gut Idee.Unit.prototype.constructor
wird gelöscht, wenn Sie so überschreibenUnit.prototype
. Diese Lösung gefällt mir allerdings sehr gut. Vielleicht könntest du es tunObject.assign(Unit.prototype, { get accreation() { ... } });
.Field
festlegen.Um Setter und Getter "innerhalb des Prototyps des Objekts" zu definieren, müssen Sie Folgendes tun:
Object.defineProperties(obj.__proto__, {"property_name": {get: getfn, set: setfn}})
Sie können dies mit einer Utility-Funktion kurzschließen:
//creates get/set properties inside an object's proto function prop (propname, getfn, setfn) { var obj = {}; obj[propname] = { get: getfn, set: setfn }; Object.defineProperties(this, obj); } function Product () { this.name = "Product"; this.amount = 10; this.price = 1; this.discount = 0; } //how to use prop function prop.apply(Product.prototype, ["total", function(){ return this.amount * this.price}]); pr = new Product(); console.log(pr.total);
Hier verwenden wir prop.apply, um den Kontext Product.prototype als "this" festzulegen, wenn wir ihn aufrufen.
Mit diesem Code beenden Sie mit einer get / set-Eigenschaft im Prototyp des Objekts, nicht in der Instanz, wie in der Frage gestellt.
(Getesteter Firefox 42, Chrome 45)
quelle
pr.total
fehlschlägt. In der Praxis ist es wahrscheinlich am besten, eine Setter-Funktion zu übergeben, um einen Fehler auszulösen, wenn nur ein Getter erstellt werden soll.Geben Sie einen Getter oder Setter in Konstruktoren mit der Object.defineProperty () -Methode an. Diese Methode verwendet drei Argumente: Das erste Argument ist das Objekt, dem die Eigenschaft hinzugefügt werden soll, das zweite ist der Name der Eigenschaft und das dritte ist der Deskriptor der Eigenschaft. Zum Beispiel können wir den Konstruktor für unser Personenobjekt wie folgt definieren:
var Employee = (function() { function EmployeeConstructor() { this.first = ""; this.last = ""; Object.defineProperty( this, "fullName", { get: function() { return this.first + " " + this.last; }, set: function(value) { var parts = value.toString().split(" "); this.name = parts[0] || ""; this.last = parts[1] || ""; } }); } return EmployeeConstructor; }());
Die Verwendung von Object.defineProperty () bietet mehr Kontrolle über unsere Eigenschaftsdefinition. Beispielsweise können wir angeben, ob die von uns beschriebene Eigenschaft dynamisch gelöscht oder neu definiert werden kann, ob ihr Wert geändert werden kann usw.
Wir können solche Einschränkungen vornehmen, indem wir die folgenden Eigenschaften des Deskriptorobjekts festlegen:
quelle
Hier ist ein einfaches Beispiel für die
Animal → Dog
Vererbung mitAnimal
einem Getter und einem Setter :////////////////////////////////////////// // General Animal constructor function Animal({age, name}) { // if-statements prevent triggering the setter on initialization if(name) this.name = name if(age) this.age = age } // an alias "age" must be used, so the setter & getter can use an // alternative variable, to avoid using "this.age", which will cause // a stack overflow of "infinite" call stack when setting the value. Object.defineProperty(Animal.prototype, "age", { get(){ console.log("Get age:", this.name, this._age) // getting return this._age }, set(value){ this._age = value console.log("Set age:", this.name, this._age) // setting } }) ////////////////////////////////////////// // Specific Animal (Dog) constructor function Dog({age = 0, name = 'dog'}) { this.name = name this.age = age } // first, defined inheritance Dog.prototype = new Animal({}); // add whatever additional methods to the prototype of Dog Object.assign(Dog.prototype, { bark(woff){ console.log(woff) } }) ////////////////////////////////////////// // Instanciating var koko = new Animal({age:300, name:'koko'}) var dog1 = new Dog({age:1, name:'blacky'}) var dog2 = new Dog({age:5, name:'shorty'}) console.log(dog1) koko.age dog1.age = 3; dog1.age dog2.age
quelle