Function.prototype.bind()
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Diebind()
-Methode vonFunction
-Instanzen erstellt eine neue Funktion, die, wenn sie aufgerufen wird, diese Funktion mit ihremthis
-Schlüsselwort auf den angegebenen Wert gesetzt aufruft, und eine gegebene Sequenz von Argumenten vor denjenigen bereitstellt, die beim Aufruf der neuen Funktion bereitgestellt werden.
Probieren Sie es aus
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: undefinedconst boundGetX = unboundGetX.bind(module);console.log(boundGetX());// Expected output: 42
Syntax
bind(thisArg)bind(thisArg, arg1)bind(thisArg, arg1, arg2)bind(thisArg, arg1, arg2, /* …, */ argN)
Parameter
thisArg
Der Wert, der als
this
-Parameter an die Ziel-Funktionfunc
übergeben wird, wenn die gebundene Funktion aufgerufen wird. Wenn die Funktion nicht imstrict mode ist, werdennull
undundefined
durch das globale Objekt ersetzt, und primitive Werte werden in Objekte umgewandelt. Der Wert wird ignoriert, wenn die gebundene Funktion mit demnew
-Operator konstruiert wird.arg1
, …,argN
OptionalArgumente, die den Argumenten vorangestellt werden, die bei der Ausführung von
func
an die gebundene Funktion übergeben werden.
Rückgabewert
Eine Kopie der angegebenen Funktion mit dem spezifiziertenthis
-Wert und anfänglichen Argumenten (falls vorhanden).
Beschreibung
Diebind()
-Funktion erstellt eine neuegebundene Funktion. Der Aufruf der gebundenen Funktion führt im Allgemeinen zur Ausführung der Funktion, die sie umschließt, welche auch dieZiel-Funktion genannt wird. Die gebundene Funktion speichert die übergebenen Parameter – die den Wert vonthis
und die ersten Argumente enthalten – als ihren internen Zustand. Diese Werte werden im Voraus gespeichert, anstatt zur Aufrufzeit übergeben zu werden. Sie können im Allgemeinenconst boundFn = fn.bind(thisArg, arg1, arg2)
als äquivalent zuconst boundFn = (...restArgs) => fn.call(thisArg, arg1, arg2, ...restArgs)
für die Wirkung beim Aufruf sehen (aber nicht beim Konstruieren vonboundFn
).
Eine gebundene Funktion kann durch Aufruf vonboundFn.bind(thisArg, /* weitere args */)
weiter gebunden werden, was eine weitere gebundene FunktionboundFn2
erstellt. Der neu gebundenethisArg
-Wert wird ignoriert, da die Ziel-Funktion vonboundFn2
, dieboundFn
ist, bereits ein gebundenesthis
hat. WennboundFn2
aufgerufen wird, ruft esboundFn
auf, was wiederumfn
aufruft. Die Argumente, diefn
letztendlich erhält, sind in der Reihenfolge: die vonboundFn
gebundenen Argumente, die vonboundFn2
gebundenen Argumente und die vonboundFn2
empfangenen Argumente.
"use strict"; // prevent `this` from being boxed into the wrapper objectfunction 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 demnew
-Operator konstruiert werden, wenn ihre Ziel-Funktion konstruierbar ist. Dies wirkt so, als ob die Ziel-Funktion stattdessen konstruiert worden wäre. Die vorangestellten Argumente werden wie üblich an die Ziel-Funktion übergeben, während der bereitgestelltethis
-Wert ignoriert wird (da Konstruktion ihr eigenesthis
vorbereitet, wie bei den Parametern vonReflect.construct
sichtbar). Wenn die gebundene Funktion direkt konstruiert wird, wirdnew.target
die Ziel-Funktion anstatt. (Das heißt, die gebundene Funktion ist fürnew.target
transparent.)
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 dieprototype
-Eigenschaft hat, kann sie nicht als Basisklasse fürextends
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 voninstanceof
verwendet wird, würdeinstanceof
nach der Ziel-Funktion (die intern in der gebundenen Funktion gespeichert ist) greifen und ihrenprototype
lesen.
class Base {}const BoundBase = Base.bind(null, 1, 2);console.log(new Base() instanceof BoundBase); // true
Die gebundene Funktion hat die folgenden Eigenschaften:
length
Der
length
der Ziel-Funktion minus die Anzahl der gebundenen Argumente (ohne denthisArg
-Parameter zu zählen), wobei 0 der Mindestwert ist.name
Der
name
der Ziel-Funktion plus ein"bound "
-Präfix.
Die gebundene Funktion erbt auch diePrototype-Kette der Ziel-Funktion. Sie hat jedoch keine anderen eigenen Eigenschaften der Ziel-Funktion (wiestatische Eigenschaften, wenn die Ziel-Funktion eine Klasse ist).
Beispiele
Eine gebundene Funktion erstellen
Die häufigste Verwendung vonbind()
besteht darin, eine Funktion zu erstellen, die, egal wie sie aufgerufen wird, mit einem bestimmtenthis
-Wert aufgerufen wird.
Ein häufiger Fehler für neue JavaScript-Programmierer ist es, eine Methode aus einem Objekt zu extrahieren, dann diese Funktion später aufzurufen und zu erwarten, dass sie das ursprüngliche Objekt als ihrthis
verwendet (z.B. durch Verwendung der Methode in rückrufbasierter Code).
Ohne besondere Vorsichtsmaßnahmen geht jedoch das ursprüngliche Objekt normalerweise verloren. Durch das Erstellen einer gebundenen Funktion aus der Funktion unter Verwendung des ursprünglichen Objekts kann dieses Problem elegant gelöst werden:
// 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()); // 81const 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 imstrict mode ausführen, wird derthis
-Parameter vonretrieveX
aufundefined
gebunden anstatt aufglobalThis
, was dazu führt, dass der Aufruf vonretrieveX()
fehlschlägt.
Wenn Sie dieses Beispiel in einem ECMAScript-Modul ausführen, wird das oberstethis
aufundefined
gebunden anstatt aufglobalThis
, was dazu führt, dass die Zuweisungthis.x = 9
fehlschlägt.
Wenn Sie dieses Beispiel in einem Node CommonJS-Modul ausführen, wird das oberstethis
aufmodule.exports
gebunden anstatt aufglobalThis
. Derthis
-Parameter vonretrieveX
wird jedoch in non-strict mode noch aufglobalThis
gebunden und in strict mode aufundefined
. Daher wird in non-strict mode (der Voreinstellung) der Aufruf vonretrieveX()
undefined
zurückgeben, weilthis.x = 9
auf ein anderes Objekt (module.exports
) schreibt als von demgetX
liest (globalThis
).
Tatsächlich sind einige eingebauten "Methoden" auch Getter, die gebundene Funktionen zurückgeben — ein bemerkenswertes Beispiel istIntl.NumberFormat.prototype.format()
, die bei Zugriff eine gebundene Funktion zurückgibt, die Sie direkt als Rückruf weitergeben können.
Partiell angewendete Funktionen
Eine weitere Verwendung vonbind()
besteht darin, eine Funktion mit vordefinierten Anfangsargumenten zu erstellen.
Diese Argumente (falls vorhanden) folgen dem bereitgestelltenthis
-Wert und werden dann am Anfang der Argumente eingefügt, die an die Ziel-Funktion weitergegeben werden, gefolgt von allen Argumenten, die zur Zeitpunkt des Aufrufs an die gebundene 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 argumentconst 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)); // 42console.log(addThirtySeven(5, 10)); // 42// (the last argument 10 is ignored)
Mit setTimeout()
Standardmäßig wird innerhalb vonsetTimeout()
dasthis
-Schlüsselwort aufglobalThis
gesetzt, das in Browsernwindow
ist. Wenn Sie mit Klassenmethoden arbeiten, die erfordern, dassthis
auf Klasseninstanzen verweist, können Siethis
explizit an die Rückruffunktion binden, um die Instanz beizubehalten.
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 können hierfür auchPfeilfunktionen verwenden.
class LateBloomer { bloom() { // Declare bloom after a delay of 1 second setTimeout(() => this.declare(), 1000); }}
Gebundene Funktionen, die als Konstruktoren verwendet werden
Gebundene Funktionen sind automatisch für die Verwendung mit demnew
-Operator geeignet, um neue Instanzen zu konstruieren, die von der Ziel-Funktion erstellt werden. Wenn eine gebundene Funktion verwendet wird, um einen Wert zu konstruieren, wird das bereitgestelltethis
ignoriert. Es werden jedoch weiterhin bereitgestellte Argumente vor dem Konstruktorruf eingefügt.
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 ignoredconst YAxisPoint = Point.bind(null, 0 /* x */);const axisPoint = new YAxisPoint(5);axisPoint.toString(); // '0,5'axisPoint instanceof Point; // trueaxisPoint instanceof YAxisPoint; // truenew YAxisPoint(17, 42) instanceof Point; // true
Beachten Sie, dass Sie nichts Besonderes tun müssen, um eine gebundene Funktion zur Verwendung mitnew
zu erstellen.new.target
,instanceof
,this
usw. funktionieren alle wie erwartet, als ob der Konstruktor nie gebunden wäre. Der einzige Unterschied ist, dass er nicht mehr fürextends
verwendet werden kann.
Die Folge davon ist, dass Sie nichts Besonderes tun müssen, um eine gebundene Funktion zu erstellen, die einfach aufgerufen werden kann, selbst wenn Sie lieber verlangen würden, dass die gebundene Funktion nur unter Verwendung vonnew
aufgerufen wird. Wenn Sie sie ohnenew
aufrufen, wird das gebundenethis
plötzlich 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 outsideconsole.log(emptyObj); // { x: 0, y: 13 }
Wenn Sie eine gebundene Funktion nur mitnew
aufrufbar oder nur ohnenew
aufrufbar machen möchten, muss die Ziel-Funktion diese Einschränkung durchsetzen, z.B. durch Überprüfung vonnew.target !== undefined
oder Verwendung einerKlasse.
Binden von Klassen
Die Verwendung vonbind()
bei Klassen erhält die meisten Semantiken der Klasse, wobei jedoch alle statischen eigenen Eigenschaften der aktuellen Klasse verloren gehen. Da jedoch die Prototype-Kette erhalten bleibt, können Sie dennoch auf statische Eigenschaften der übergeordneten Klasse zugreifen.
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); // undefinedconsole.log(new BoundDerived() instanceof Derived); // true
Methoden in Utility-Funktionen umwandeln
bind()
ist auch in Fällen hilfreich, bei denen Sie eine Methode, die einen spezifischenthis
-Wert erfordert, in eine einfache Utility-Funktion umwandeln möchten, die den vorherigenthis
-Parameter als normalen Parameter akzeptiert. Dies ist ähnlich wie allgemeine Utility-Funktionen: anstattarray.map(callback)
aufzurufen, verwenden Siemap(array, callback)
, wodurch Siemap
mit array-ähnlichen Objekten verwenden können, die keine Arrays sind (z.B.arguments
), ohneObject.prototype
zu ändern.
Nehmen SieArray.prototype.slice()
, zum Beispiel, das Sie verwenden möchten, um ein array-ähnliches Objekt in ein echtes Array zu konvertieren. Sie könnten eine Abkürzung erstellen wie diese:
const slice = Array.prototype.slice;// …slice.call(arguments);
Beachten Sie, dass Sieslice.call
nicht speichern und als einfache Funktion aufrufen können, weil diecall()
-Methode auch ihrenthis
-Wert liest, was die Funktion ist, die sie aufrufen soll. In diesem Fall können Siebind()
verwenden, um den Wert vonthis
fürcall()
zu binden. Im folgenden Code istslice()
eine gebundene Version vonFunction.prototype.call()
, wobei derthis
-Wert anArray.prototype.slice()
gebunden ist. Dies bedeutet, dass zusätzlichecall()
-Aufrufe eliminiert werden können:
// Same as "slice" in the previous exampleconst unboundSlice = Array.prototype.slice;const slice = Function.prototype.call.bind(unboundSlice);// …slice(arguments);
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-function.prototype.bind |
Browser-Kompatibilität
Siehe auch
MDN-Feedback-Box
Diese Seite wurde automatisch aus dem Englischen übersetzt.