Was ist das Schlüsselwort „new“ in JavaScript?

Lesezeit: 10 Minuten

Was ist das Schlusselwort „new in JavaScript
Alon Gubkin

Die new Schlüsselwort in JavaScript kann ziemlich verwirrend sein, wenn man es zum ersten Mal antrifft, da die Leute dazu neigen zu denken, dass JavaScript keine objektorientierte Programmiersprache ist.

  • Was ist es?
  • Welche Probleme löst es?
  • Wann ist es angebracht und wann nicht?

Es macht 5 Dinge:

  1. Es erstellt ein neues Objekt. Der Typ dieses Objekts ist einfach Objekt.
  2. Es setzt die internen, unzugänglichen, [[prototype]] (dh __proto__)-Eigenschaft als externe, zugängliche, Prototyp Objekt (jedes Funktionsobjekt hat automatisch eine Prototyp Eigentum).
  3. Es macht die this Variable zeigen auf das neu erstellte Objekt.
  4. Es führt die Konstruktorfunktion aus und verwendet dabei immer das neu erstellte Objekt this wird genannt.
  5. Es gibt das neu erstellte Objekt zurück, es sei denn, die Konstruktorfunktion gibt ein Nicht-null Objektbezug. In diesem Fall wird stattdessen diese Objektreferenz zurückgegeben.

Notiz: Konstruktorfunktion bezieht sich auf die Funktion nach dem new Stichwort, wie in

new ConstructorFunction(arg1, arg2)

Sobald dies geschehen ist und eine undefinierte Eigenschaft des neuen Objekts angefordert wird, überprüft das Skript die des Objekts [[prototype]] Objekt für die Eigenschaft statt. So können Sie in JavaScript etwas Ähnliches wie bei der traditionellen Klassenvererbung erreichen.

Der schwierigste Teil dabei ist Punkt Nummer 2. Jedes Objekt (einschließlich Funktionen) hat diese interne Eigenschaft, die aufgerufen wird [[prototype]]. Es kann nur zum Zeitpunkt der Objekterstellung festgelegt werden, entweder mit Neumit Objekt.erstellen, oder basierend auf dem Literal (Funktionen standardmäßig auf Function.prototype, Zahlen auf Number.prototype usw.). Es kann nur mit gelesen werden Object.getPrototypeOf(someObject). Es gibt Nein andere Möglichkeit, diesen Wert einzustellen oder zu lesen.

Funktionen, zusätzlich zu den versteckten [[prototype]] Eigenschaft, haben auch eine Eigenschaft namens Prototypund darauf können Sie zugreifen und es ändern, um geerbte Eigenschaften und Methoden für die von Ihnen erstellten Objekte bereitzustellen.


Hier ist ein Beispiel:

ObjMaker = function() {this.a="first";};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

Es ist wie Klassenvererbung, weil jetzt alle Objekte, die Sie erstellen, verwendet werden new ObjMaker() scheint auch die Eigenschaft ‘b’ geerbt zu haben.

Wenn Sie so etwas wie eine Unterklasse wollen, dann tun Sie dies:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c="third";  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

Ich habe eine Menge Müll zu diesem Thema gelesen, bevor ich es endlich gefunden habe diese Seitewo dies sehr gut mit schönen Diagrammen erklärt wird.

  • Wollte nur hinzufügen: Es gibt tatsächlich eine Möglichkeit, auf das Interne zuzugreifen [[prototype]], von __proto__. Dies ist jedoch kein Standard und wird nur von relativ neuen Browsern (und nicht von allen) unterstützt. Es gibt einen standardisierten Weg, nämlich Object.getPrototypeOf(obj), aber es ist Ecmascript3.1 und wird selbst nur von neuen Browsern unterstützt – wieder einmal. Es wird im Allgemeinen empfohlen, diese Eigenschaft nicht zu verwenden, da die Dinge dort sehr schnell kompliziert werden.

    – Blubb

    14. April 2011 um 14:55 Uhr


  • Frage: Was passiert anders, wenn ObjMaker ist als eine Funktion definiert, die einen Wert zurückgibt?

    – Jim Blackler

    27. Februar 2012 um 19:05 Uhr

  • @LonelyPixel new existiert damit du es nicht musst Factory-Methoden schreiben, um Funktionen/Objekte zu konstruieren/kopieren. Es bedeutet: “Kopieren Sie dies und machen Sie es genauso wie seine übergeordnete ‘Klasse’; tun Sie dies effizient und korrekt; und speichern Sie Vererbungsinformationen, auf die nur ich, JS, intern zugreifen kann”. Dazu modifiziert es das ansonsten unzugängliche Interne prototype des neuen Objekts, um die geerbten Mitglieder undurchsichtig zu kapseln und klassische OO-Vererbungsketten nachzuahmen (die zur Laufzeit nicht modifizierbar sind). Sie können dies ohne simulieren new, aber die Vererbung kann zur Laufzeit geändert werden. Gut? Schlecht? Wie du willst.

    – Techniker

    23. Oktober 2012 um 22:36 Uhr


  • Ein kleiner Punkt zum Hinzufügen: ein Aufruf an einen Konstruktor, wenn ihm das Schlüsselwort new vorausgeht, gibt automatisch das erstellte Objekt zurück; Es besteht keine Notwendigkeit, es explizit innerhalb des Konstruktors zurückzugeben.

    – Charlie Roberts

    6. Juni 2013 um 2:04 Uhr

  • Es gibt eine Notiz, die besagt Notice that this pattern is deprecated!. Was ist das richtige aktuelle Muster, um den Prototyp einer Klasse festzulegen?

    – Tom Pažourek

    17. Februar 2014 um 12:18 Uhr

Was ist das Schlusselwort „new in JavaScript
JulianR

Angenommen, Sie haben diese Funktion:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};

Wenn Sie dies als eigenständige Funktion so aufrufen:

Foo();

Durch Ausführen dieser Funktion werden zwei Eigenschaften zu hinzugefügt window Objekt (A und B). Es fügt es dem hinzu window da window ist das Objekt, das die Funktion aufgerufen hat, wenn Sie sie so ausführen, und this in einer Funktion ist das Objekt, das die Funktion aufgerufen hat. Zumindest in Javascript.

Nennen Sie es jetzt so mit new:

var bar = new Foo();

Was passiert, wenn Sie hinzufügen new zu einem Funktionsaufruf besteht darin, dass ein neues Objekt erstellt wird (nur var bar = new Object()) und dass die this innerhalb der Funktion zeigt auf das Neue Object Sie gerade erstellt haben, anstatt an das Objekt, das die Funktion aufgerufen hat. Damit bar ist jetzt ein Objekt mit den Eigenschaften A und B. Jede Funktion kann ein Konstruktor sein, es macht nur nicht immer Sinn.

  • Hängt vom Ausführungskontext ab. In meinem Fall (Qt-Skripting) ist es nur ein globales Objekt.

    – MaksymB

    21. Januar 2013 um 13:24 Uhr

  • Wird dies zu mehr Speicherverbrauch führen?

    – Jürgen Paul

    24. Juli 2013 um 19:20 Uhr

  • weil window das Objekt ist, das die Funktion aufgerufen hat – muss sein: weil Fenster das Objekt ist, das enthält die Funktion.

    – Dávid Horváth

    23. Juli 2016 um 13:22 Uhr

  • @Taurus In einem Webbrowser ist eine Nicht-Methodenfunktion eine Methode von window implizit. Auch in einer Schließung, wenn auch anonym. Im Beispiel handelt es sich jedoch um einen einfachen Methodenaufruf im Fenster: Foo(); => [default context].Foo(); => window.Foo();. In diesem Ausdruck window ist der Kontext (nicht nur die Anruferwas egal ist).

    – Dávid Horváth

    11. September 2017 um 11:47 Uhr


  • @Taurus Grundsätzlich ja. In ECMA 6 und 7 sind die Dinge jedoch komplexer (siehe Lambdas, Klassen usw.).

    – Dávid Horváth

    11. September 2017 um 12:00 Uhr

1646817314 228 Was ist das Schlusselwort „new in JavaScript
Basilikum

Zusätzlich zu Daniel Howards Antwort ist hier was new tut (oder scheint zumindest zu tun):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

Während

var obj = New(A, 1, 2);

ist äquivalent zu

var obj = new A(1, 2);

  • Ich fand, dass Javascript einfacher zu verstehen ist als Englisch: v

    – Feuchthut

    20. Oktober 2013 um 10:11 Uhr

  • Ausgezeichnete Antwort. Ich habe eine winzige Frage: Wie kann das möglich sein? func.prototype zu sein null? Könnten Sie das bitte etwas näher erläutern?

    – Tom Pažourek

    2. April 2014 um 11:12 Uhr

  • @tomp Sie könnten die Prototyp-Eigenschaft überschreiben, indem Sie einfach schreiben A.prototype = null; In diesem Fall new A() wird zu einem Objekt führen, auf das der interne Prototyp zeigt Object Objekt: jsfiddle.net/Mk42Z

    – Basilikum

    28. April 2014 um 18:19 Uhr

  • Die Art der Prüfung könnte falsch sein, da ein Host-Objekt etwas anderes als “Objekt” oder “Funktion” erzeugen könnte. Um zu testen, ob etwas ein Objekt ist, ziehe ich es vor Object(ret) === ret.

    – Oriol

    8. Oktober 2015 um 21:40 Uhr

  • @Oriol danke für den Kommentar. Es ist wahr, was Sie sagen, und jeder tatsächliche Test sollte robuster durchgeführt werden. Allerdings denke ich für diese konzeptionelle Antwort, die typeof test macht es nur einfacher zu verstehen, was hinter den Kulissen vor sich geht.

    – Basilikum

    8. Oktober 2015 um 21:53 Uhr

Was ist das Schlusselwort „new in JavaScript
Ring S

Für Anfänger zum besseren Verständnis

Probieren Sie den folgenden Code in der Browserkonsole aus.

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

a instanceof Window;  // true
a instanceof Foo;     // false

b instanceof Window;  // false
b instanceof Foo;     // true

Jetzt können Sie die Community-Wiki-Antwort lesen 🙂

1646817315 309 Was ist das Schlusselwort „new in JavaScript
meder omuraliew

Es ist also wahrscheinlich nicht zum Erstellen von Objektinstanzen gedacht

Es wird genau dafür verwendet. Sie definieren einen Funktionskonstruktor wie folgt:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

Der zusätzliche Vorteil von ECMAScript besteht jedoch darin, dass Sie es mit erweitern können .prototype Eigentum, also können wir so etwas tun wie…

Person.prototype.getName = function() { return this.name; }

Alle von diesem Konstruktor erstellten Objekte haben jetzt eine getName aufgrund der Prototypkette, auf die sie Zugriff haben.

  • Funktionskonstruktoren werden wie Klassen verwendet, es gibt keine class Schlüsselwort, aber Sie können so ziemlich dasselbe tun.

    – meder omuraliev

    29. Oktober 2009 um 21:37 Uhr

  • Es gibt so etwas wie ein class-Schlüsselwort – class ist für die zukünftige Verwendung reserviert

    – Greg

    29. Oktober 2009 um 21:41 Uhr

  • Das ist übrigens der Grund, warum Sie .className und nicht .class verwenden, um eine CSS-Klasse festzulegen

    – Greg

    29. Oktober 2009 um 21:41 Uhr

1646817315 111 Was ist das Schlusselwort „new in JavaScript
Hyperschnecke

JavaScript ist eine objektorientierte Programmiersprache und wird genau zum Erstellen von Instanzen verwendet. Es ist eher prototypbasiert als klassenbasiert, aber das bedeutet nicht, dass es nicht objektorientiert ist.

  • Funktionskonstruktoren werden wie Klassen verwendet, es gibt keine class Schlüsselwort, aber Sie können so ziemlich dasselbe tun.

    – meder omuraliev

    29. Oktober 2009 um 21:37 Uhr

  • Es gibt so etwas wie ein class-Schlüsselwort – class ist für die zukünftige Verwendung reserviert

    – Greg

    29. Oktober 2009 um 21:41 Uhr

  • Das ist übrigens der Grund, warum Sie .className und nicht .class verwenden, um eine CSS-Klasse festzulegen

    – Greg

    29. Oktober 2009 um 21:41 Uhr

Zusammenfassung:

Die new Das Schlüsselwort wird in Javascript verwendet, um ein Objekt aus einer Konstruktorfunktion zu erstellen. Die new Schlüsselwort muss vor dem Konstruktor-Funktionsaufruf platziert werden und wird die folgenden Dinge tun:

  1. Erstellt ein neues Objekt
  2. Legt den Prototyp dieses Objekts auf die Prototyp-Eigenschaft der Konstruktorfunktion fest
  3. Bindet die this Schlüsselwort auf das neu erstellte Objekt und führt die Konstruktorfunktion aus
  4. Gibt das neu erstellte Objekt zurück

Beispiel:

function Dog (age) {
  this.age = age;
}

const doggie = new Dog(12);

console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true

Was genau passiert:

  1. const doggie sagt: Wir brauchen Speicher, um eine Variable zu deklarieren.
  2. Der Zuweisungsoperator = sagt: Wir werden diese Variable mit dem Ausdruck nach dem initialisieren =
  3. Der Ausdruck ist new Dog(12). Die JS-Engine sieht das neue Schlüsselwort, erstellt ein neues Objekt und setzt den Prototyp auf Dog.prototype
  4. Die Konstruktorfunktion wird mit ausgeführt this Wert auf das neue Objekt gesetzt. In diesem Schritt wird dem neu erstellten Hundeobjekt das Alter zugewiesen.
  5. Das neu erstellte Objekt wird zurückgegeben und der Variablen doggie zugewiesen.

981660cookie-checkWas ist das Schlüsselwort „new“ in JavaScript?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy