| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Juli 2015 browserbergreifend verfgbar.
Die bind()-Methode von Function-Instanzen erstellt eine neue Funktion, die, wenn sie aufgerufen wird, diese Funktion mit ihrem this-Schlsselwort, das auf den bereitgestellten Wert gesetzt ist, und einer gegebenen Abfolge von Argumenten, welche den bei Aufruf der neuen Funktion bereitgestellten Argumenten vorausgehen, ausfhrt.
const module = {
x: 42,
getX() {
return this.x;
},
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42
bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* , */ argN)
thisArgDer Wert, der als this-Parameter an die Ziel-Funktion func bergeben wird, wenn die gebundene Funktion aufgerufen wird. Wenn die Funktion nicht im Strict-Modus ist, werden null und undefined mit dem globalen Objekt ersetzt, und primitive Werte werden in Objekte umgewandelt. Der Wert wird ignoriert, wenn die gebundene Funktion mit dem new-Operator erzeugt wird.
arg1, , argN OptionalArgumente, die den Argumenten vorangestellt werden, welche an die gebundene Funktion beim Aufruf von func bergeben werden.
Eine Kopie der bergebenen Funktion mit dem angegebenen this-Wert und den initialen Argumenten (falls angegeben).
Die bind()-Funktion erstellt eine neue gebundene Funktion. Das Aufrufen dieser gebundenen Funktion resultiert in der Regel in der Ausfhrung der Funktion, die sie umschliet, welche auch als Ziel-Funktion bezeichnet wird. Die gebundene Funktion speichert die bergebenen Parameter dazu gehren der Wert von this und die ersten Argumente als ihren internen Zustand. Diese Werte werden im Voraus gespeichert, anstatt bei der Ausfhrung bergeben zu werden. Man kann im Allgemeinen const boundFn = fn.bind(thisArg, arg1, arg2) als quivalent zu const boundFn = (...restArgs) => fn.call(thisArg, arg1, arg2, ...restArgs) betrachten, was den Effekt beim Aufruf betrifft (aber nicht, wenn boundFn konstruiert wird).
Eine gebundene Funktion kann weiter gebunden werden, indem boundFn.bind(thisArg, /* more args */) aufgerufen wird, was eine weitere gebundene Funktion boundFn2 erstellt. Der neu gebundene thisArg-Wert wird ignoriert, weil die Ziel-Funktion von boundFn2, die boundFn ist, bereits ein gebundenes this hat. Wenn boundFn2 aufgerufen wird, ruft es boundFn auf, welches wiederum fn aufruft. Die Argumente, die fn letztlich erhlt, sind in der Reihenfolge: die Argumente, die von boundFn gebunden sind, die von boundFn2 gebundenen Argumente und die von boundFn2 empfangenen Argumente.
"use strict"; // prevent `this` from being boxed into the wrapper object
function log(...args) {
console.log(this, ...args);
}
const boundLog = log.bind("this value", 1, 2);
const boundLog2 = boundLog.bind("new this value", 3, 4);
boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6
Eine gebundene Funktion kann auch mit dem new-Operator konstruiert werden, wenn ihre Ziel-Funktion konstruierbar ist. Dies wirkt so, als ob die Ziel-Funktion stattdessen konstruiert worden wre. Die vorangestellten Argumente werden der Ziel-Funktion wie gewohnt bergeben, whrend der bereitgestellte this-Wert ignoriert wird (weil der Konstruktion ein eigenes this vorbereitet, wie an den Parametern von Reflect.construct zu sehen ist). Wenn die gebundene Funktion direkt konstruiert wird, ist new.target die Ziel-Funktion. (Das bedeutet, dass die gebundene Funktion fr new.target transparent ist.)
class Base {
constructor(...args) {
console.log(new.target === Base);
console.log(args);
}
}
const BoundBase = Base.bind(null, 1, 2);
new BoundBase(3, 4); // true, [1, 2, 3, 4]
Da eine gebundene Funktion jedoch nicht die prototype-Eigenschaft hat, kann sie nicht als Basisklasse fr extends verwendet werden.
class Derived extends class {}.bind(null) {}
// TypeError: Class extends value does not have valid prototype property undefined
Wenn eine gebundene Funktion als rechte Seite von instanceof verwendet wird, wrde instanceof nach der Ziel-Funktion greifen (die intern in der gebundenen Funktion gespeichert ist) und deren prototype lesen.
class Base {}
const BoundBase = Base.bind(null, 1, 2);
console.log(new Base() instanceof BoundBase); // true
Die gebundene Funktion hat die folgenden Eigenschaften:
lengthDie length der Ziel-Funktion minus der Anzahl der zu bindenden Argumente (ohne den thisArg-Parameter zu zhlen), wobei 0 der Minimalwert ist.
nameDer name der Ziel-Funktion plus ein "bound "-Prfix.
Die gebundene Funktion erbt auch die Prototypenkette der Ziel-Funktion. Sie hat jedoch nicht andere eigene Eigenschaften der Ziel-Funktion (wie statische Eigenschaften, wenn die Ziel-Funktion eine Klasse ist).
Die hufigste Verwendung von bind() besteht darin, eine Funktion zu erstellen, die unabhngig davon, wie sie aufgerufen wird, mit einem bestimmten this-Wert aufgerufen wird.
Ein hufiger Fehler bei neuen JavaScript-Programmierern ist es, eine Methode aus einem Objekt zu extrahieren, dann diese Funktion aufzurufen und zu erwarten, dass sie das ursprngliche Objekt als this verwendet (z.B. indem die Methode in callback-basiertem Code verwendet wird).
Ohne besondere Vorsicht geht das ursprngliche Objekt jedoch normalerweise verloren. Das Erstellen einer gebundenen Funktion aus der Funktion unter Verwendung des ursprnglichen Objekts lst dieses Problem elegant:
// Top-level 'this' is bound to 'globalThis' in scripts.
this.x = 9;
const module = {
x: 81,
getX() {
return this.x;
},
};
// The 'this' parameter of 'getX' is bound to 'module'.
console.log(module.getX()); // 81
const retrieveX = module.getX;
// The 'this' parameter of 'retrieveX' is bound to 'globalThis' in non-strict mode.
console.log(retrieveX()); // 9
// Create a new function 'boundGetX' with the 'this' parameter bound to 'module'.
const boundGetX = retrieveX.bind(module);
console.log(boundGetX()); // 81
Hinweis:
Wenn Sie dieses Beispiel im Strict-Modus ausfhren, wird der this-Parameter von retrieveX auf undefined anstatt auf globalThis gebunden, was dazu fhrt, dass der retrieveX()-Aufruf fehlschlgt.
Wenn Sie dieses Beispiel in einem ECMAScript-Modul ausfhren, wird das top-level this auf undefined anstatt auf globalThis gebunden, was dazu fhrt, dass die Zuweisung this.x = 9 fehlschlgt.
Wenn Sie dieses Beispiel in einem Node CommonJS-Modul ausfhren, wird das Top-Level-this auf module.exports anstatt auf globalThis gebunden. Der this-Parameter von retrieveX wird jedoch in nicht-striktem Modus weiterhin an globalThis gebunden und in strengem Modus an undefined. Daher wird im nicht-strikten Modus (der Standard) der retrieveX()-Aufruf undefined zurckgeben, da this.x = 9 auf ein anderes Objekt (module.exports) schreibt, als von dem getX liest (globalThis).
Tatschlich sind einige eingebaute "Methoden" auch Getter, die gebundene Funktionen zurckgeben ein bemerkenswertes Beispiel ist Intl.NumberFormat.prototype.format(), das, wenn darauf zugegriffen wird, eine gebundene Funktion zurckgibt, die Sie direkt als Callback verwenden knnen.
Eine weitere Verwendung von bind() besteht darin, eine Funktion mit vorgegebenen Anfangsargumenten zu erstellen.
Diese Argumente (falls vorhanden) folgen dem bereitgestellten this-Wert und werden dann am Anfang der an die Ziel-Funktion bergebenen Argumente eingefgt, gefolgt von den Argumenten, die beim Aufruf der gebundenen Funktion bergeben werden.
function list(...args) {
return args;
}
function addArguments(arg1, arg2) {
return arg1 + arg2;
}
console.log(list(1, 2, 3)); // [1, 2, 3]
console.log(addArguments(1, 2)); // 3
// Create a function with a preset leading argument
const leadingThirtySevenList = list.bind(null, 37);
// Create a function with a preset first argument.
const addThirtySeven = addArguments.bind(null, 37);
console.log(leadingThirtySevenList()); // [37]
console.log(leadingThirtySevenList(1, 2, 3)); // [37, 1, 2, 3]
console.log(addThirtySeven(5)); // 42
console.log(addThirtySeven(5, 10)); // 42
// (the last argument 10 is ignored)
Per Standard wird innerhalb von setTimeout() das this-Schlsselwort auf globalThis gesetzt, welches in Browsern dem window entspricht. Beim Arbeiten mit Klassenmethoden, die this bentigen, um auf Klasseninstanzen zu verweisen, knnen Sie this explizit an die Callback-Funktion binden, um die Instanz zu erhalten.
class LateBloomer {
constructor() {
this.petalCount = Math.floor(Math.random() * 12) + 1;
}
bloom() {
// Declare bloom after a delay of 1 second
setTimeout(this.declare.bind(this), 1000);
}
declare() {
console.log(`I am a beautiful flower with ${this.petalCount} petals!`);
}
}
const flower = new LateBloomer();
flower.bloom();
// After 1 second, calls 'flower.declare()'
Sie knnen auch Arrow-Funktionen fr diesen Zweck verwenden.
class LateBloomer {
bloom() {
// Declare bloom after a delay of 1 second
setTimeout(() => this.declare(), 1000);
}
}
Gebundene Funktionen sind automatisch geeignet fr die Verwendung mit dem new-Operator, um neue Instanzen zu erstellen, die durch die Ziel-Funktion erzeugt wurden. Wenn eine gebundene Funktion verwendet wird, um einen Wert zu konstruieren, wird das bereitgestellte this ignoriert. Die bereitgestellten Argumente werden jedoch immer noch dem Konstruktoraufruf vorangestellt.
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return `${this.x},${this.y}`;
};
const p = new Point(1, 2);
p.toString();
// '1,2'
// The thisArg's value doesn't matter because it's ignored
const YAxisPoint = Point.bind(null, 0 /* x */);
const axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'
axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new YAxisPoint(17, 42) instanceof Point; // true
Beachten Sie, dass Sie nichts Besonderes tun mssen, um eine gebundene Funktion fr die Verwendung mit new zu erstellen. new.target, instanceof, this usw. funktionieren wie erwartet, als wre der Konstruktor nie gebunden. Der einzige Unterschied ist, dass sie nicht mehr fr extends verwendet werden kann.
Die Schlussfolgerung ist, dass Sie nichts Besonderes tun mssen, um eine gebundene Funktion zu erstellen, die schlicht aufgerufen werden soll, selbst wenn Sie mchten, dass die gebundene Funktion nur mit new aufgerufen wird. Wenn Sie sie ohne new aufrufen, wird das gebundene this pltzlich nicht ignoriert.
const emptyObj = {};
const YAxisPoint = Point.bind(emptyObj, 0 /* x */);
// Can still be called as a normal function
// (although usually this is undesirable)
YAxisPoint(13);
// The modifications to `this` is now observable from the outside
console.log(emptyObj); // { x: 0, y: 13 }
Wenn Sie mchten, dass eine gebundene Funktion nur mit new aufgerufen werden kann, oder nur ohne new aufgerufen werden kann, muss die Ziel-Funktion diese Einschrnkung durchsetzen, z.B. indem sie prft, ob new.target !== undefined oder indem sie eine Klasse verwendet.
Die Verwendung von bind() bei Klassen bewahrt die meisten Semantiken der Klasse, auer dass alle statischen eigenen Eigenschaften der aktuellen Klasse verloren gehen. Da jedoch die Prototypenkette bewahrt wird, knnen Sie weiterhin auf statische Eigenschaften zugreifen, die von der Elternklasse geerbt werden.
class Base {
static baseProp = "base";
}
class Derived extends Base {
static derivedProp = "derived";
}
const BoundDerived = Derived.bind(null);
console.log(BoundDerived.baseProp); // "base"
console.log(BoundDerived.derivedProp); // undefined
console.log(new BoundDerived() instanceof Derived); // true
bind() ist auch hilfreich in Fllen, in denen Sie eine Methode, die einen bestimmten this-Wert bentigt, in eine einfache Hilfsfunktion umwandeln mchten, die den vorherigen this-Parameter als normalen Parameter akzeptiert. Dies ist hnlich wie bei allgemeinen Hilfsfunktionen: anstatt array.map(callback) aufzurufen, verwenden Sie map(array, callback), was es Ihnen erlaubt, map mit array-hnlichen Objekten zu verwenden, die keine Arrays sind (zum Beispiel arguments), ohne Object.prototype zu verndern.
Nehmen Sie Array.prototype.slice() als Beispiel, das Sie verwenden mchten, um ein array-hnliches Objekt in ein echtes Array zu konvertieren. Sie knnten eine Abkrzung wie diese erstellen:
const slice = Array.prototype.slice;
//
slice.call(arguments);
Beachten Sie, dass Sie slice.call nicht speichern und als einfache Funktion aufrufen knnen, da die call()-Methode auch ihren this-Wert liest, welcher die Funktion ist, die sie aufrufen soll. In diesem Fall knnen Sie bind() verwenden, um den Wert von this fr call() zu binden. Im folgenden Codebeispiel ist slice() eine gebundene Version von Function.prototype.call(), wobei der this-Wert an Array.prototype.slice() gebunden ist. Dies bedeutet, dass zustzliche call()-Aufrufe vermieden werden knnen:
// Same as "slice" in the previous example
const unboundSlice = Array.prototype.slice;
const slice = Function.prototype.call.bind(unboundSlice);
//
slice(arguments);
| Spezifikation |
|---|
| ECMAScript 2027 LanguageSpecification # sec-function.prototype.bind |
Function.prototype.bind in core-jsFunction.prototype.apply()Function.prototype.call()FunctionObject/FunctionDer Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |