Angenommen, ich habe ein Foo
Objekt
Wie kann ich dieses Objekt durch Hinzufügen einer bar()
Methode erweitern und sicherstellen, dass zukünftige Instanzen Foo
diese Methode haben?
quelle
Angenommen, ich habe ein Foo
Objekt
Wie kann ich dieses Objekt durch Hinzufügen einer bar()
Methode erweitern und sicherstellen, dass zukünftige Instanzen Foo
diese Methode haben?
Sie müssen es zu Protos Prototyp hinzufügen:
function Foo(){}
Foo.prototype.bar = function(){}
var x = new Foo()
x.bar()
Dies hängt alles davon ab, wie Sie erstellen Foo
und wie Sie es verwenden möchten .bar()
.
Verwenden Sie zunächst eine Konstruktorfunktion für Ihr Objekt?
var myFoo = new Foo();
Wenn ja, können Sie Foo
die prototype
Eigenschaft der Funktion .bar
wie folgt erweitern:
function Foo () { /*...*/ }
Foo.prototype.bar = function () { /*...*/ };
var myFoo = new Foo();
myFoo.bar();
Auf diese Weise hat jede Instanz von Foo
jetzt Zugriff auf die gleiche Instanz von .bar
.
Nämlich: .bar
uneingeschränkter Zugang haben this
, aber hat absolut keinen Zugang zu variables
in der Konstruktorfunktion:
function Foo () { var secret = 38; this.name = "Bob"; }
Foo.prototype.bar = function () { console.log(secret); };
Foo.prototype.otherFunc = function () { console.log(this.name); };
var myFoo = new Foo();
myFoo.otherFunc(); // "Bob";
myFoo.bar(); // error -- `secret` is undefined...
// ...or a value of `secret` in a higher/global scope
Auf andere Weise können Sie eine Funktion definieren, um ein beliebiges Objekt (nicht this
) zurückzugeben, .bar
das als Eigenschaft dieses Objekts erstellt wurde:
function giveMeObj () {
var private = 42,
privateBar = function () { console.log(private); },
public_interface = {
bar : privateBar
};
return public_interface;
}
var myObj = giveMeObj();
myObj.bar(); // 42
Auf diese Weise haben Sie eine Funktion, die neue Objekte erstellt.
Für jedes dieser Objekte wurde eine .bar
Funktion erstellt.
Jede .bar
Funktion hat über den sogenannten Abschluss Zugriff auf die "privaten" Variablen innerhalb der Funktion, die ihr bestimmtes Objekt zurückgegeben haben.
Jeder hat .bar
weiterhin Zugriff auf this
, da this
, wenn Sie die Funktion aufrufen, wie myObj.bar();
immer auf myObj
( public_interface
in meinem Beispiel Foo
) Bezug genommen wird .
Der Nachteil dieses Formats ist, dass, wenn Sie Millionen dieser Objekte erstellen, dies auch Millionen von Kopien sind .bar
, die in den Speicher gelangen.
Sie können dies auch innerhalb einer Konstruktorfunktion tun und innerhalb des Konstruktors this.bar = function () {};
festlegen. Wiederum wäre der Closure-Zugriff auf private Variablen im Konstruktor der Vorteil und der Nachteil wäre ein erhöhter Speicherbedarf.
Die erste Frage lautet also:
Erwarten Sie, dass Ihre Methoden Zugriff auf das Lesen / Ändern von "privaten" Daten haben, auf die nicht über das Objekt selbst (durch this
oder myObj.X
) zugegriffen werden kann ?
und die zweite Frage ist: Machen Sie genug aus diesen Objekten, so dass die Erinnerung ein großes Problem sein wird, wenn Sie ihnen jeweils ihre eigene persönliche Funktion geben, anstatt ihnen eine zum Teilen zu geben?
Wenn Sie beispielsweise jedem Dreieck und jeder Textur .draw
in einem High-End-3D-Spiel eine eigene Funktion geben würden, wäre dies möglicherweise übertrieben und würde wahrscheinlich die Framerate in einem so heiklen System beeinflussen ...
Wenn Sie jedoch 5 Bildlaufleisten pro Seite erstellen möchten und möchten, dass jede ihre Position festlegen und verfolgen kann, ob sie gezogen wird, ohne dass jede andere Anwendung Zugriff auf das Lesen / Festlegen derselben Elemente hat Dann gibt es wirklich keinen Grund zur Angst, dass 5 zusätzliche Funktionen Ihre App töten werden, vorausgesetzt, sie ist möglicherweise bereits 10.000 Zeilen lang (oder länger).
Es gibt viele Möglichkeiten, wiederverwendbare Objekte wie dieses in JavaScript zu erstellen. Mozilla hat hier eine schöne Einführung:
In Ihrem Beispiel funktioniert Folgendes:
function Foo(){
this.bar = function (){
alert("Hello World!");
}
}
myFoo = new Foo();
myFoo.bar(); // Hello World
Sie können bar zu einer Funktion machen, die es zu einer Methode macht.
Foo.bar = function(passvariable){ };
Als Eigenschaft würde ihm nur eine Zeichenfolge, ein Datentyp oder ein Boolescher Wert zugewiesen
Foo.bar = "a place";