JavaScript: Class.method vs. Class.prototype.method
498
Was ist der Unterschied zwischen den folgenden beiden Erklärungen?
Class.method =function(){/* code */}Class.prototype.method =function(){/* code using this.values */}
Ist es in Ordnung, sich die erste Anweisung als Deklaration einer statischen Methode und die zweite Anweisung als Deklaration einer Instanzmethode vorzustellen?
Ja, die erste Funktion hat keine Beziehung zu einer Objektinstanz dieser Konstruktorfunktion . Sie können sie als 'statische Methode' betrachten .
In JavaScript sind Funktionen erstklassige Objekte, dh Sie können sie wie jedes Objekt behandeln. In diesem Fall fügen Sie dem Funktionsobjekt nur eine Eigenschaft hinzu .
Die zweite Funktion, wenn Sie den Prototyp der Konstruktorfunktion erweitern, steht allen mit dem newSchlüsselwort erstellten Objektinstanzen zur Verfügung , und der Kontext innerhalb dieser Funktion (das thisSchlüsselwort) bezieht sich auf die tatsächliche Objektinstanz, in der Sie sie aufrufen.
Betrachten Sie dieses Beispiel:
// constructor functionfunctionMyClass(){var privateVariable;// private member only available within the constructor fnthis.privilegedMethod =function(){// it can access private members//..};}// A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instanceMyClass.staticMethod =function(){};MyClass.prototype.publicMethod =function(){// the 'this' keyword refers to the object instance// you can access only 'privileged' and 'public' members};var myObj =newMyClass();// new object instance
myObj.publicMethod();MyClass.staticMethod();
Aber warum ist Function.prototype.method == Function.method?
Raghavendra
1
@ Raghavendra ist es nicht
Zorgatone
1
@ Menda Ihr Link ist tot
Eugen Sunic
19
Wenn Sie mehr als eine Instanz von MyClass erstellen, befindet sich immer noch nur eine Instanz von publicMethod im Speicher. Bei privilegedMethod werden jedoch viele Instanzen erstellt, und staticMethod hat keine Beziehung zu einer Objektinstanz.
Deshalb sparen Prototypen Speicher.
Wenn Sie die Eigenschaften des übergeordneten Objekts ändern und die entsprechende Eigenschaft des Kindes nicht geändert wurde, wird sie aktualisiert.
Für visuelle Lernende beim Definieren der Funktion ohne .prototype
ExampleClass=function(){};ExampleClass.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// >> output: `called from func def.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// >> error! `someInstance.method is not a function`
Mit dem gleichen Code, wenn .prototypehinzugefügt wird,
ExampleClass.prototype.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// > error! `ExampleClass.method is not a function.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// > output: `Called from instance`
Um es klarer zu machen,
ExampleClass=function(){};ExampleClass.directM =function(){}//M for methodExampleClass.prototype.protoM =function(){}var instanceOfExample =newExampleClass();ExampleClass.directM();✓ works
instanceOfExample.directM(); x Error!ExampleClass.protoM(); x Error!
instanceOfExample.protoM();✓ works
**** Beachten Sie für das obige Beispiel, dass someInstance.method () nicht ausgeführt wird, da
ExampleClass.method () Fehler verursacht und die Ausführung nicht fortgesetzt werden kann.
Aber zur Veranschaulichung und zum leichteren Verständnis habe ich diese Reihenfolge beibehalten. ****
Ergebnisse generiert aus chrome developer console&
Klicken Sie oben auf den Link jsbin, um den Code zu durchlaufen.
Kommentierten Abschnitt mit + umschaltenJS Bin
Sehen Sie sich an, wie das staticSchlüsselwort zum Deklarieren der statischen Methode verwendet wurde isPerson.
So erstellen Sie ein PersonKlassenobjekt.
const aminu = new Person("Aminu", "Abubakar");
Mit der statischen Methode isPerson.
Person.isPerson(aminu); // will return true
Verwenden der Instanzmethode sayHi.
aminu.sayHi(); // will return "Hi Aminu"
HINWEIS: Beide Beispiele sind im Wesentlichen gleich. JavaScript bleibt eine klassenlose Sprache. Das classin ES6 eingeführte Modell ist in erster Linie ein syntaktischer Zucker gegenüber dem vorhandenen prototypbasierten Vererbungsmodell.
"In ES6" beschreiben Sie nur einen Syntaxzucker. Dies ist nicht die "ES2015" -Methode (bitte jeder hört auf, ES6 zu verwenden, verwenden Sie den richtigen Begriff ES2015). Es ist einfach eine andere Art und meiner Meinung nach die falsche.
K - Die Toxizität in SO nimmt zu.
2
@KarlMorrison Aminu hat nicht "way of do it" geschrieben. Sie haben das einfach selbst geschrieben und eine Ausnahme gemacht. Ihr Standpunkt mag in Bezug auf ES6 und ES2015 fair sein, aber in Gesprächen wird häufig auf eine kürzere Konvention zurückgegriffen, um die Effizienz zu verbessern. Daher halte ich es nicht für möglich oder sicher ratsam, sie aus dem Schreiben zu entfernen.
Wuliwong
Vielen Dank für den ES6-Teil Ihrer Antwort. das verdeutlicht viel, besonders wenn es mit den 2 obigen "öffentlichen + privilegierten" Antworten kombiniert wird. Ich bin aber gründlich von Ihrem verwirrt obj.constructor === PersonSein trueBeispiel wenn ... Whaaaat? Wie kann der Konstruktor einer Klasseninstanz ===die Klasse selbst ...? (Das ist so, als würde man sagen, dass eine Teilmenge einer Menge die Menge selbst ist usw.)
Andrew
Ohhh ... ist das alles, um zu sagen, dass der Konstruktor buchstäblich alles ist, was eine JS-Klasse am Ende des Tages wirklich ist? Alles andere ist entweder im Konstruktor gestapelt oder ein völlig statisches Konstrukt, das von der Klasse isoliert ist, außer nach Name / Konzept (und wie ein implizites "dies", das offensichtlich verfügbar gemacht wird)? (Was ich also für eine Teilmenge der Menge hielt, war eigentlich keine Teilmenge.)
Wenn Sie mehr als eine Instanz von MyClass erstellen, befindet sich immer noch nur eine Instanz von publicMethod im Speicher. Bei privilegedMethod werden jedoch viele Instanzen erstellt, und staticMethod hat keine Beziehung zu einer Objektinstanz.
Deshalb sparen Prototypen Speicher.
Wenn Sie die Eigenschaften des übergeordneten Objekts ändern und die entsprechende Eigenschaft des Kindes nicht geändert wurde, wird sie aktualisiert.
quelle
Für visuelle Lernende beim Definieren der Funktion ohne
.prototype
Mit dem gleichen Code, wenn
.prototype
hinzugefügt wird,Um es klarer zu machen,
**** Beachten Sie für das obige Beispiel, dass someInstance.method () nicht ausgeführt wird, da
ExampleClass.method () Fehler verursacht und die Ausführung nicht fortgesetzt werden kann.
Aber zur Veranschaulichung und zum leichteren Verständnis habe ich diese Reihenfolge beibehalten. ****
Ergebnisse generiert aus
chrome developer console
& Klicken Sie oben auf den Link jsbin, um den Code zu durchlaufen. Kommentierten Abschnitt mit + umschaltenJS Bin
ctrl/
quelle
Ja, der erste wird
static method
auch genanntclass method
, während der zweite ein istinstance method
.Betrachten Sie die folgenden Beispiele, um sie genauer zu verstehen.
In ES5
Im obigen Code
isPerson
handelt es sich um eine statische Methode, währendsayHi
es sich um eine Instanzmethode von handeltPerson
.Im Folgenden wird beschrieben, wie Sie ein Objekt aus dem
Person
Konstruktor erstellen .var aminu = new Person("Aminu", "Abubakar");
Mit der statischen Methode
isPerson
.Person.isPerson(aminu); // will return true
Verwenden der Instanzmethode
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
In ES6
Sehen Sie sich an, wie das
static
Schlüsselwort zum Deklarieren der statischen Methode verwendet wurdeisPerson
.So erstellen Sie ein
Person
Klassenobjekt.const aminu = new Person("Aminu", "Abubakar");
Mit der statischen Methode
isPerson
.Person.isPerson(aminu); // will return true
Verwenden der Instanzmethode
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
HINWEIS: Beide Beispiele sind im Wesentlichen gleich. JavaScript bleibt eine klassenlose Sprache. Das
class
in ES6 eingeführte Modell ist in erster Linie ein syntaktischer Zucker gegenüber dem vorhandenen prototypbasierten Vererbungsmodell.quelle
obj.constructor === Person
Seintrue
Beispiel wenn ... Whaaaat? Wie kann der Konstruktor einer Klasseninstanz===
die Klasse selbst ...? (Das ist so, als würde man sagen, dass eine Teilmenge einer Menge die Menge selbst ist usw.)