597 Stimmen

Gilt das Schlüsselwort "new" in JavaScript als schädlich?

In einem anderen Frage wies ein Nutzer darauf hin, dass die new Schlüsselwort gefährlich war, und schlug eine Lösung für die Objekterstellung vor, bei der keine new . Ich habe nicht geglaubt, dass das stimmt, vor allem, weil ich Prototype, Scriptaculous und andere hervorragende JavaScript-Bibliotheken verwendet habe, und jede von ihnen hat die new Stichwort.

Trotzdem habe ich gestern den Vortrag von Douglas Crockford im YUI-Theater gesehen und er sagte genau das Gleiche, dass er die new Schlüsselwort nicht mehr in seinem Code ( Crockford über JavaScript - Akt III: Die ultimative Funktion - 50:23 Minuten ).

Ist es "schlecht", die new Stichwort? Was sind die Vor- und Nachteile seiner Verwendung?

97 Stimmen

Es ist NICHT "schlecht", das Schlüsselwort new zu verwenden. Aber wenn Sie es vergessen, rufen Sie den Objektkonstruktor wie eine normale Funktion auf. Wenn Ihr Konstruktor seinen Ausführungskontext nicht überprüft, wird er nicht bemerken, dass "this" auf ein anderes Objekt (normalerweise das globale Objekt) statt auf die neue Instanz zeigt. Daher wird Ihr Konstruktor Eigenschaften und Methoden zum globalen Objekt (Fenster) hinzufügen. Wenn Sie in der Objektfunktion immer prüfen, ob "this" eine Instanz Ihres Objekts ist, werden Sie dieses Problem nie haben.

6 Stimmen

Ich kann das nicht verstehen. Einerseits rät Doug von der Verwendung von new . Aber wenn Sie sich die YUI-Bibliothek ansehen. Sie haben zu verwenden new überall. Wie zum Beispiel var myDataSource = new Y.DataSource.IO({source:"./myScript.php"}); .

2 Stimmen

@aditya_gaur Das liegt daran, dass man, wenn man eine Initialisierung eines Objekts benötigt, eine init Methode, wenn Sie die Object.create Ansatz und rufen Sie danach an. Viel einfacher ist es, einfach zu verwenden new der beides tut, die Prototypenkette setzt und einen Initialisierungscode aufruft.

25voto

Juan Mendes Punkte 85125

Ich habe einen Beitrag darüber geschrieben, wie man das Problem des Aufrufs eines Konstruktors ohne die neu Stichwort.

Es ist hauptsächlich didaktisch, aber es zeigt, wie Sie Konstruktoren erstellen können, die mit oder ohne neu und erfordert nicht die Hinzufügung von Standardcode zum Test este in jedem Konstruktor.

Konstrukteure ohne Verwendung von "new"

Das ist das Wesentliche an dieser Technik:

/**
 * Wraps the passed in constructor so it works with
 * or without the new keyword
 * @param {Function} realCtor The constructor function.
 *    Note that this is going to be wrapped
 *    and should not be used directly
 */
function ctor(realCtor) {
  // This is going to be the actual constructor
  return function wrapperCtor() {
    var obj; // The object that will be created
    if (this instanceof wrapperCtor) {
      // Called with new
      obj = this;
    } else {
      // Called without new. Create an empty object of the
      // correct type without running that constructor
      surrogateCtor.prototype = wrapperCtor.prototype;
      obj = new surrogateCtor();
    }
    // Call the real constructor function
    realCtor.apply(obj, arguments);
    return obj;
  }

  function surrogateCtor() {}
}

So verwenden Sie es:

// Create our point constructor
Point = ctor(function(x, y) {
  this.x = x;
  this.y = y;
});

// This is good
var pt = new Point(20, 30);
// This is OK also
var pt2 = Point(20, 30);

22voto

Greg Dean Punkte 27938

Der Grund für die Nichtverwendung des neu Stichwort, ist einfach:

Indem Sie es überhaupt nicht verwenden, vermeiden Sie den Fall, dass Sie es versehentlich weglassen. Das Konstruktionsmuster, das YUI verwendet, ist ein Beispiel dafür, wie Sie das neue Schlüsselwort ganz vermeiden können:

var foo = function () {
    var pub = { };
    return pub;
}
var bar = foo();

Alternativ können Sie auch dies tun:

function foo() { }
var bar = new foo();

Dabei besteht jedoch die Gefahr, dass jemand vergisst, die neu Schlüsselwort, und das este Operator, der alle FUBAR . Soweit ich weiß, gibt es keinen Vorteil, dies zu tun (außer, dass Sie es gewohnt sind).

Am Ende des Tages: Es geht darum, defensiv zu sein. Können Sie die neue Erklärung verwenden? Ja. Wird Ihr Code dadurch gefährlicher? Ja.

Wenn Sie schon einmal C++ geschrieben haben, ist das so ähnlich wie das Setzen von Zeigern auf NULL, nachdem Sie sie gelöscht haben.

20voto

PEZ Punkte 16398

Ich denke, "neu" macht den Code klarer. Und Klarheit ist alles wert. Es ist gut zu wissen, dass es Fallstricke gibt, aber sie zu vermeiden, indem man Klarheit vermeidet, scheint mir nicht der richtige Weg zu sein.

15voto

nyuszika7h Punkte 13065

Fall 1: new ist nicht erforderlich und sollte vermieden werden

var str = new String('asd');  // type: object
var str = String('asd');      // type: string

var num = new Number(12);     // type: object
var num = Number(12);         // type: number

Fall 2: new ist erforderlich, sonst erhalten Sie eine Fehlermeldung

new Date().getFullYear();     // correct, returns the current year, i.e. 2010
Date().getFullYear();         // invalid, returns an error

12voto

alegscogs Punkte 5731

Hier ist die kürzeste Zusammenfassung der beiden stärksten Argumente für und gegen die Verwendung der new Betreiber:

Argumente gegen new

  1. Funktionen, die für als Objekte instanziiert werden können, indem die new Betreibers kann katastrophale Folgen haben Auswirkungen haben, wenn sie fälschlicherweise als normale Funktionen aufgerufen werden. A Funktionscode wird in einem solchen Fall wird in dem Bereich ausgeführt, in dem die Funktion aufgerufen wird, und nicht im dem Bereich eines lokalen Objekts beabsichtigt. Dies kann dazu führen, dass globale Variablen und Eigenschaften zu überschrieben werden, was katastrophale Folgen.
  2. Schließlich, Schreiben function Func() , und ruft dann Func.prototype und fügen Sie Dinge hinzu, damit Sie aufrufen können new Func() zu konstruieren Ihr Objekt scheint hässlich für einige Programmierer, die lieber ein eine andere Art der Objektvererbung aus architektonischen und stilistischen Gründen.

Weitere Informationen zu diesem Argument finden Sie unter Douglas Crockford Das großartige und prägnante Buch _JavaScript: Die guten Seiten_ . Probieren Sie es trotzdem aus.

Argumente zugunsten von new

  1. Die Verwendung des new Operator zusammen mit prototypisch Der Auftrag ist schnell.
  2. Die Sache mit dem Versehen den Code einer Konstruktorfunktion Code im globalen Namensraum auszuführen, kann leicht verhindert werden, wenn Sie immer ein Stückchen Code in Ihre Konstruktorfunktionen einfügen, um zu prüfen um zu prüfen, ob sie aufgerufen werden korrekt aufgerufen werden, und in den Fällen, in denen sie es nicht sind, den Aufruf wie gewünscht behandeln.

見る John Resig's Beitrag für eine einfache Erklärung dieser Technik und für eine allgemein tiefergehende Erklärung des von ihm befürworteten Vererbungsmodells.

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