1920 Stimmen

Was ist das Schlüsselwort "new" in JavaScript?

El new Schlüsselwort in JavaScript kann beim ersten Mal ziemlich verwirrend sein, da die meisten Leute denken, dass JavaScript keine objektorientierte Programmiersprache ist.

  • Was ist das?
  • Welche Probleme werden damit gelöst?
  • Wann ist es angebracht und wann nicht?

2297voto

Daniel Howard Punkte 7556

Es tut 5 Dinge:

  1. Es wird ein neues Objekt erstellt. Der Typ dieses Objekts ist einfach Objekt .
  2. Es setzt dieses neue Objekt intern, unzugänglich, [[Prototyp]] (d.h. __proto__ ) als externe, zugängliche Eigenschaft der Konstruktorfunktion, Prototyp Objekt (jedes Funktionsobjekt hat automatisch eine Prototyp Eigenschaft).
  3. Es macht die this Variable auf das neu erstellte Objekt verweisen.
  4. Er führt die Konstruktorfunktion aus und verwendet das neu erstellte Objekt, wenn this erwähnt wird.
  5. Sie gibt das neu erstellte Objekt zurück, es sei denn, die Konstruktorfunktion gibt ein nicht null Objektreferenz. In diesem Fall wird stattdessen dieser Objektverweis zurückgegeben.

Nota: Konstruktorfunktion bezieht sich auf die Funktion nach der new Schlüsselwort, wie in

new ConstructorFunction(arg1, arg2)

Wenn dies geschehen ist und eine undefinierte Eigenschaft des neuen Objekts angefordert wird, prüft das Skript die [[Prototyp]] Objekt für die Eigenschaft. Auf diese Weise können Sie etwas Ähnliches wie die traditionelle Klassenvererbung in JavaScript erreichen.

Der schwierigste Teil ist dabei Punkt 2. Jedes Objekt (einschließlich Funktionen) hat diese interne Eigenschaft namens [[Prototyp]] . Es kann nur zur Zeit der Objekterzeugung gesetzt werden, entweder mit neu con Objekt.erstellen oder auf der Grundlage des Literals (Funktionen standardmäßig mit Function.prototype, Zahlen mit Number.prototype usw.). Es kann nur gelesen werden mit Object.getPrototypeOf(someObject) . Es gibt keine eine andere Möglichkeit, diesen Wert zu setzen oder zu lesen.

Funktionen, zusätzlich zu den versteckten [[Prototyp]] Eigenschaft, haben auch eine Eigenschaft namens Prototyp Auf diese können Sie zugreifen und sie verändern, um vererbte 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, denn jetzt werden alle Objekte, die Sie mit 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 Unsinn zu diesem Thema gelesen, bevor ich schließlich auf diese Seite , wo dies sehr gut mit schönen Diagrammen erklärt wird.

452voto

JulianR Punkte 15805

Angenommen, Sie haben diese Funktion:

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

Wenn Sie diese Funktion als eigenständige Funktion aufrufen, etwa so:

Foo();

Das Ausführen dieser Funktion fügt zwei Eigenschaften zur window Objekt ( A y B ). Er fügt sie der window denn 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.

Rufen Sie es nun so auf mit new :

var bar = new Foo();

Was passiert, wenn Sie Folgendes hinzufügen new eines Funktionsaufrufs ist, dass ein neues Objekt erstellt wird (nur var bar = new Object() ) und dass die this innerhalb der Funktion verweist auf den neuen Object die Sie gerade erstellt haben, statt zu dem Objekt, das die Funktion aufgerufen hat. Also bar ist nun ein Objekt mit den Eigenschaften A y B . Jede Funktion kann ein Konstruktor sein, es macht nur nicht immer Sinn.

178voto

basilikum Punkte 9984

Zusätzlich zur Antwort von Daniel Howard gibt es folgende Informationen new tut (oder zumindest zu tun scheint):

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 gleichbedeutend mit

var obj = new A(1, 2);

138voto

Anulal S Punkte 6274

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 :)

41voto

meder omuraliev Punkte 177513

also ist es wahrscheinlich nicht zum Erstellen Instanzen von Objekten

Er 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 ist jedoch, dass man mit der .prototype Eigenschaft, so dass wir etwas tun können wie...

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

Alle Objekte, die mit diesem Konstruktor erzeugt werden, haben nun eine getName aufgrund der Prototypenkette, zu der sie Zugang haben.

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