A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/new.target below:

new.target - JavaScript | MDN

new.target

Baseline Widely available

Die new.target Meta-Eigenschaft ermöglicht es Ihnen zu erkennen, ob eine Funktion oder ein Konstruktor mit dem new Operator aufgerufen wurde. In Konstruktoren und Funktionen, die mit dem new Operator aufgerufen wurden, gibt new.target eine Referenz auf den Konstruktor oder die Funktion zurück, auf die new angewendet wurde. Bei normalen Funktionsaufrufen ist new.target undefined.

Probieren Sie es aus
function Foo() {
  if (!new.target) {
    throw new TypeError("calling Foo constructor without new is invalid");
  }
}

try {
  Foo();
} catch (e) {
  console.log(e);
  // Expected output: TypeError: calling Foo constructor without new is invalid
}
Syntax Wert

new.target ist garantiert ein konstruierbarer Funktionswert oder undefined.

Beschreibung

Die new.target Syntax besteht aus dem Schlüsselwort new, einem Punkt und dem Bezeichner target. Da new ein reserviertes Wort ist und kein Bezeichner, handelt es sich hierbei nicht um einen Property-Accessor, sondern um eine spezielle Ausdruckssyntax.

Die new.target Meta-Eigenschaft ist in allen Funktions-/Klassenkörpern verfügbar; die Verwendung von new.target außerhalb von Funktionen oder Klassen führt zu einem Syntaxfehler.

Beispiele new.target in Funktionsaufrufen

Bei normalen Funktionsaufrufen (im Gegensatz zu Konstruktionsaufrufen von Funktionen) ist new.target undefined. Dies ermöglicht es Ihnen zu erkennen, ob eine Funktion mit new als Konstruktor aufgerufen wurde.

function Foo() {
  if (!new.target) {
    throw new Error("Foo() must be called with new");
  }
  console.log("Foo instantiated with new");
}

new Foo(); // Logs "Foo instantiated with new"
Foo(); // Throws "Foo() must be called with new"
new.target in Konstruktoren

In Klassenkonstruktoren bezieht sich new.target auf den Konstruktor, der direkt von new aufgerufen wurde. Dies ist auch der Fall, wenn der Konstruktor in einer Elternklasse ist und von einem Kinderkonstruktor delegiert wurde. new.target zeigt auf die Klasse, auf die new angewendet wurde. Zum Beispiel wurde bei der Initialisierung von b mit new B() der Name von B ausgegeben; und ähnlich im Fall von a, wurde der Name der Klasse A ausgegeben.

class A {
  constructor() {
    console.log(new.target.name);
  }
}

class B extends A {
  constructor() {
    super();
  }
}

const a = new A(); // Logs "A"
const b = new B(); // Logs "B"
new.target unter Verwendung von Reflect.construct()

Vor Reflect.construct() oder Klassen war es üblich, Vererbung zu implementieren, indem der Wert von this übergeben und der Basiskonstruktor modifiziert wurde.

function Base() {
  this.name = "Base";
}

function Extended() {
  // Only way to make the Base() constructor work on the existing
  // `this` value instead of a new object that `new` creates.
  Base.call(this);
  this.otherProperty = "Extended";
}

Object.setPrototypeOf(Extended.prototype, Base.prototype);
Object.setPrototypeOf(Extended, Base);

console.log(new Extended()); // Extended { name: 'Base', otherProperty: 'Extended' }

Allerdings rufen call() und apply() die Funktion tatsächlich auf, anstatt sie zu konstruieren, daher hat new.target den Wert undefined. Dies bedeutet, dass, wenn Base() überprüft, ob es mit new konstruiert wurde, ein Fehler ausgelöst wird, oder es kann auf andere unerwartete Weise verhalten werden. Zum Beispiel können Sie Map nicht auf diese Weise erweitern, da der Map() Konstruktor nicht ohne new aufgerufen werden kann.

Alle eingebauten Konstruktoren konstruieren direkt die gesamte Prototypenkette der neuen Instanz, indem new.target.prototype gelesen wird. Um sicherzustellen, dass (1) Base mit new konstruiert wird, und (2) new.target auf die Unterklasse anstatt auf Base selbst zeigt, müssen wir Reflect.construct() verwenden.

function BetterMap(entries) {
  // Call the base class constructor, but setting `new.target` to the subclass,
  // so that the instance created has the correct prototype chain.
  return Reflect.construct(Map, [entries], BetterMap);
}

BetterMap.prototype.upsert = function (key, actions) {
  if (this.has(key)) {
    this.set(key, actions.update(this.get(key)));
  } else {
    this.set(key, actions.insert());
  }
};

Object.setPrototypeOf(BetterMap.prototype, Map.prototype);
Object.setPrototypeOf(BetterMap, Map);

const map = new BetterMap([["a", 1]]);
map.upsert("a", {
  update: (value) => value + 1,
  insert: () => 1,
});
console.log(map.get("a")); // 2

Hinweis: Tatsächlich ist es aufgrund des Fehlens von Reflect.construct() nicht möglich, grundlegende Objekte (wie Error-Subklassen) beim Transpiling zu Code vor ES6 ordnungsgemäß zu erweitern.

Wenn Sie jedoch ES6-Code schreiben, sollten Sie stattdessen Klassen und extends verwenden, da es lesbarer und weniger fehleranfällig ist.

class BetterMap extends Map {
  // The constructor is omitted because it's just the default one

  upsert(key, actions) {
    if (this.has(key)) {
      this.set(key, actions.update(this.get(key)));
    } else {
      this.set(key, actions.insert());
    }
  }
}

const map = new BetterMap([["a", 1]]);
map.upsert("a", {
  update: (value) => value + 1,
  insert: () => 1,
});
console.log(map.get("a")); // 2
Spezifikationen Browser-Kompatibilität Siehe auch

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4