832 Stimmen

Verwendung von 'prototype' vs. 'this' in JavaScript?

Was ist der Unterschied zwischen

var A = function () {
    this.x = function () {
        //do something
    };
};

et

var A = function () { };
A.prototype.x = function () {
    //do something
};

0 Stimmen

Das Konzept des Schlüsselworts THIS wird hier explizit erläutert scotch.io/@alZami/verstehen-dieses-in-javascript

3 Stimmen

Die Lektüre "dieses" Threads zeigt, wie schrecklich JS ist und wie sehr seine Prinzipien für viele Entwickler unklar sind. Was genau ist falsch an einfacher zu verstehenden Sprachen? Ich denke, es ist an der Zeit, dass die Entwickler ihre Stimme erheben, um verwirrende Technologien abzulehnen, die keinen oder nur einen geringen Nutzen für das Geschäft oder die Entwicklungsarbeit haben.

22voto

pishpish Punkte 2500

Jedes Objekt ist mit einem Prototyp-Objekt verknüpft. Wenn Sie versuchen, auf eine Eigenschaft zuzugreifen, die nicht existiert, sucht JavaScript im Prototyp-Objekt des Objekts nach dieser Eigenschaft und gibt sie zurück, wenn sie existiert.

El prototype Eigenschaft eines Funktionskonstruktors bezieht sich auf das Prototyp-Objekt aller Instanzen, die mit dieser Funktion erstellt werden, wenn man new .


In Ihrem ersten Beispiel fügen Sie eine Eigenschaft hinzu x zu jeder Instanz, die mit der Option A Funktion.

var A = function () {
    this.x = function () {
        //do something
    };
};

var a = new A();    // constructor function gets executed
                    // newly created object gets an 'x' property
                    // which is a function
a.x();              // and can be called like this

Im zweiten Beispiel fügen Sie dem Prototyp-Objekt eine Eigenschaft hinzu, die alle Instanzen, die mit A hinweisen.

var A = function () { };
A.prototype.x = function () {
    //do something
};

var a = new A();    // constructor function gets executed
                    // which does nothing in this example

a.x();              // you are trying to access the 'x' property of an instance of 'A'
                    // which does not exist
                    // so JavaScript looks for that property in the prototype object
                    // that was defined using the 'prototype' property of the constructor

Zusammenfassend lässt sich sagen, dass im ersten Beispiel jeder Instanz wird eine Kopie der Funktion zugewiesen . Im zweiten Beispiel eine einzige Kopie der Funktion wird von allen Instanzen gemeinsam genutzt .

1 Stimmen

Ich habe für diese Antwort gestimmt, weil sie am direktesten auf die Frage eingeht.

1 Stimmen

Ich mochte Ihren geradlinigen Ansatz!!

21voto

tarkabak Punkte 219

Das eigentliche Problem bei der Verwendung von this anstelle von prototype ist, dass beim Überschreiben einer Methode der Konstruktor der Basisklasse weiterhin auf die überschriebene Methode verweist. Bedenken Sie dies:

BaseClass = function() {
    var text = null;

    this.setText = function(value) {
        text = value + " BaseClass!";
    };

    this.getText = function() {
        return text;
    };

    this.setText("Hello"); // This always calls BaseClass.setText()
};

SubClass = function() {
    // setText is not overridden yet,
    // so the constructor calls the superclass' method
    BaseClass.call(this);

    // Keeping a reference to the superclass' method
    var super_setText = this.setText;
    // Overriding
    this.setText = function(value) {
        super_setText.call(this, "SubClass says: " + value);
    };
};
SubClass.prototype = new BaseClass();

var subClass = new SubClass();
console.log(subClass.getText()); // Hello BaseClass!

subClass.setText("Hello"); // setText is already overridden
console.log(subClass.getText()); // SubClass says: Hello BaseClass!

gegen:

BaseClass = function() {
    this.setText("Hello"); // This calls the overridden method
};

BaseClass.prototype.setText = function(value) {
    this.text = value + " BaseClass!";
};

BaseClass.prototype.getText = function() {
    return this.text;
};

SubClass = function() {
    // setText is already overridden, so this works as expected
    BaseClass.call(this);
};
SubClass.prototype = new BaseClass();

SubClass.prototype.setText = function(value) {
    BaseClass.prototype.setText.call(this, "SubClass says: " + value);
};

var subClass = new SubClass();
console.log(subClass.getText()); // SubClass says: Hello BaseClass!

Wenn Sie der Meinung sind, dass dies kein Problem darstellt, dann hängt es davon ab, ob Sie ohne private Variablen leben können und ob Sie erfahren genug sind, um ein Leck zu erkennen, wenn Sie eines sehen. Außerdem ist es lästig, die Konstruktorlogik nach den Methodendefinitionen zu platzieren.

var A = function (param1) {
    var privateVar = null; // Private variable

    // Calling this.setPrivateVar(param1) here would be an error

    this.setPrivateVar = function (value) {
        privateVar = value;
        console.log("setPrivateVar value set to: " + value);

        // param1 is still here, possible memory leak
        console.log("setPrivateVar has param1: " + param1);
    };

    // The constructor logic starts here possibly after
    // many lines of code that define methods

    this.setPrivateVar(param1); // This is valid
};

var a = new A(0);
// setPrivateVar value set to: 0
// setPrivateVar has param1: 0

a.setPrivateVar(1);
//setPrivateVar value set to: 1
//setPrivateVar has param1: 0

gegen:

var A = function (param1) {
    this.setPublicVar(param1); // This is valid
};
A.prototype.setPublicVar = function (value) {
    this.publicVar = value; // No private variable
};

var a = new A(0);
a.setPublicVar(1);
console.log(a.publicVar); // 1

17voto

oozzal Punkte 2401

Was ist der Unterschied? => Eine Menge.

Ich denke, die this Version wird verwendet, um die Verkapselung, d.h. das Verbergen von Daten, zu ermöglichen. Sie hilft dabei, private Variablen zu manipulieren.

Betrachten wir das folgende Beispiel:

var AdultPerson = function() {

  var age;

  this.setAge = function(val) {
    // some housekeeping
    age = val >= 18 && val;
  };

  this.getAge = function() {
    return age;
  };

  this.isValid = function() {
    return !!age;
  };
};

Nun, die prototype Struktur kann wie folgt angewendet werden:

Verschiedene Erwachsene haben ein unterschiedliches Alter, aber alle Erwachsenen haben die gleichen Rechte.
Also fügen wir es mit Prototyp hinzu, statt mit diesem.

AdultPerson.prototype.getRights = function() {
  // Should be valid
  return this.isValid() && ['Booze', 'Drive'];
};

Schauen wir uns nun die Umsetzung an.

var p1 = new AdultPerson;
p1.setAge(12); // ( age = false )
console.log(p1.getRights()); // false ( Kid alert! )
p1.setAge(19); // ( age = 19 )
console.log(p1.getRights()); // ['Booze', 'Drive'] ( Welcome AdultPerson )

var p2 = new AdultPerson;
p2.setAge(45);    
console.log(p2.getRights()); // The same getRights() method, *** not a new copy of it ***

Ich hoffe, das hilft.

3 Stimmen

+1 Eine viel weniger komplizierte und anschaulichere Antwort als die anderen. Sie sollten jedoch etwas ausführlicher werden, bevor Sie diese (guten) Beispiele anführen.

1 Stimmen

Ich bin mir nicht sicher über "diese Version wird verwendet, um eine Kapselung zu ermöglichen, d.h. um Daten zu verstecken". Wenn eine Eigenschaft innerhalb einer Funktion mit "this" wie in "this.myProperty=..." definiert wird, ist eine solche Eigenschaft nicht "privat" und kann von Objekten außerhalb der Klasse mit "new" aufgerufen werden.

17voto

Arnav Aggarwal Punkte 729

Ich weiß, dass diese Frage schon zu Tode beantwortet wurde, aber ich möchte gerne ein konkretes Beispiel für Geschwindigkeitsunterschiede zeigen.

Funktion direkt am Objekt:

function ExampleFn() {
    this.print = function() {
        console.log("Calling print! ");
    }
}

var objects = [];
console.time('x');
for (let i = 0; i < 2000000; i++) {
    objects.push(new ExampleFn());
}
console.timeEnd('x');

//x: 1151.960693359375ms

Funktion auf Prototyp:

function ExampleFn() {
}
ExampleFn.prototype.print = function() {
    console.log("Calling print!");
}

var objects = [];
console.time('y');
for (let i = 0; i < 2000000; i++) {
    objects.push(new ExampleFn());
}
console.timeEnd('y');

//x: 617.866943359375ms

Hier erstellen wir 2.000.000 neue Objekte mit einer print Methode in Chrome. Wir speichern jedes Objekt in einem Array. Einfügen von print auf dem Prototyp dauert etwa halb so lang.

2 Stimmen

Gut, dass Sie darauf hingewiesen haben! Nächstes Mal fügen Sie jedoch bitte KEINE Screenshots Ihres Codes ein, sondern kopieren und fügen Sie den Code stattdessen ein, damit andere ihn auch leicht testen/verwenden können. Dieses Mal habe ich die Bilder für Sie ersetzt.

14voto

harropriiz Punkte 455

Prototyp ist die Vorlage der Klasse, die für alle zukünftigen Instanzen der Klasse gilt. Dies hingegen ist die spezielle Instanz des Objekts.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X