Übergang von "Prototyp" und "Neu" zu einem Verschluss- und Belichtungsmuster
Ich habe den JavaScript-Code einer anderen Person überarbeitet.
VOR:
function SomeObj(flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version="1.1 (prototype)";
if (!this._someProperty) this._init();
// leading underscore hints at what should be a 'private' to me
this.reset(); // assumes reset has been added...
}
SomeObj.prototype.reset = function() {
/* perform some actions */
}
/* UPDATE */
SomeObj.prototype.getPrivate = function() {
return _private; // will return undefined
}
/* ...several other functions appended via `prototype`...*/
NACH DEM:
var SomeObj = function (flag) {
var _private = true;
this.flag = (flag) ? true : false;
this.version = "2.0 (constructor)";
this.reset = function () {
/* perform some actions */
};
/* UPDATE */
this.getPrivate = function() {
return _private; // will return true
}
/* other functions and function calls here */
}
Für mich ist das erste Beispiel schwer zu lesen, insbesondere in einem größeren Zusammenhang. Hinzufügen von Methoden wiereset
auf diese Weise mit derprototype
Eigenschaft, scheint viel weniger kontrolliert zu sein, da es vermutlich irgendwo im Skript vorkommen kann. Mein überarbeiteter Code (das zweite Beispiel oben) sieht für mich viel ordentlicher aus und ist daher einfacher zu lesen, da er in sich geschlossen ist. Ich habe mit den Variablendeklarationen etwas Privatsphäre gewonnen, aber die Möglichkeiten der Prototypenkette verloren.
...
FRAGEN:
Zunächst möchte ich wissen, was ich sonst noch durch den Verzicht verloren habeprototype
oder wenn es größere Auswirkungen auf den Verlust der Prototypkette gibt.Dieser Beitrag ist 6 Jahre alt, behauptet aber, dass mit derprototype
Eigentum ist im großen Maßstab viel effizienter als Verschlussmuster.
Beide obigen Beispiele würden immer noch durch a instanziiertnew
Operator; Sie sind beide "klassische" Konstrukteure. Irgendwann möchte ich sogar in ein Modell übergehen, in dem alle Eigenschaften und Funktionen als deklariert sindvar
s und ich haben eine Methode, die ich verfügbar mache und die in der Lage ist, ein Objekt zurückzugeben, das alle Eigenschaften und Methoden öffnet, die ich benötige.die Privilegien (aufgrund der Schließung) für diejenigen haben, die privat sind. Etwas wie das:
var SomeObj = (function () {
/* all the stuff mentioned above, declared as 'private' `var`s */
/* UPDATE */
var getPrivate = function () {
return private;
}
var expose = function (flag) {
// just returns `flag` for now
// but could expose other properties
return {
flag: flag || false, // flag from argument, or default value
getPrivate: getPrivate
}
};
return {
expose: expose
}
})(); // IIFE
// instead of having to write `var whatever = new SomeObj(true);` use...
var whatever = SomeObj.expose();
Auf StackOverflow gibt es einige Antworten auf die Frage „Prototyp vs. Abschluss“ (Hier undHier, zum Beispiel). Aber wie bei derprototype
Ich bin interessiert, was für eine Bewegung in diese Richtung und weg von dernew
Operator bedeutet für die Effizienz meines Codes und für den Verlust von Möglichkeiten (z.instanceof
ist verloren). Wenn ich sowieso keine prototypische Vererbung verwenden werde, verliere ich tatsächlich etwas, wenn ich auf die verzichtenew
Operator?
Eine lockerere Frage, wenn ich die Erlaubnis dazu habe, da ich oben nach Einzelheiten frage: ifprototype
undnew
Gibt es Richtlinien oder Entwurfsmuster, um sie auf eine ordentlichere Art und Weise zu schreiben?
...
AKTUALISIEREN:Beachten Sie, dassexpose
Gibt jedes Mal ein neues Objekt zurück. In diesem Fall erfolgt die Instanziierung. So wie ich das verstehe, bezieht sich dieses Objekt auf Methoden, die in der deklariert sindSomeObj
Schließen, sie sind die gleichen Methoden für alle Objekte (sofern nicht überschrieben). Im Falle derflag
Variable (die ich jetzt korrigiert habe), kann dies aus dem Argument von geerbt werdenexpose
, haben einen Standardwert oder verweisen erneut auf eine eingekapselte, bereits vorhandene Methode oder Eigenschaft. Es gibt also Fälle, in denen Objekte produziert werden, und es gibt eine Vererbung (plus Polymorphismus?), Die hier stattfindet.
Um also Frage 2 zu wiederholen: Wenn ich ohnehin keine prototypische Vererbung verwenden werde, verliere ich tatsächlich etwas, wenn ich auf die verzichtenew
Operator?
Vielen Dank für die bisherigen Antworten, die zur Klärung meiner Frage beigetragen haben.