aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/global_objects/function/bind/index.html
blob: 9427e62299354f08d69eb4f2654b806895001b17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
---
title: Function.prototype.bind()
slug: Web/JavaScript/Reference/Global_Objects/Function/bind
tags:
  - Class
  - ECMAScript 2015
  - ECMAScript 5
  - Function
  - JavaScript
  - Method
  - bind
  - polyfill
translation_of: Web/JavaScript/Reference/Global_Objects/Function/bind
---
<div>{{JSRef}}</div>

<p>Die <strong><code>bind()</code></strong> Methode erzeugt eine neue Funktion die beim Aufruf ihr <code>this</code> Schlüsselwort auf den ersten übergebenen Wert setzt. Alle weiteren Argumente werden den beim Funktionsaufruf übergebenen Werten vorangestellt.</p>

<div>{{EmbedInteractiveExample("pages/js/function-bind.html", "taller")}}</div>



<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox"><var>fun</var>ction.bind(<var>thisArg</var>[, <var>arg1</var>[, <var>arg2</var>[, ...]]])</pre>

<h3 id="Parameter">Parameter</h3>

<dl>
 <dt><code>thisArg</code></dt>
 <dd>Der für <code>this</code> zu übergebende Wert an die Zielfunktion sobald die gebundene Funktion aufgerufen wird. Der Wert wird ignoriert, wenn die gebundene Funktion mit dem {{jsxref("Operators/new", "new")}} Schlüsselwort initiiert wurde.</dd>
 <dt><code>arg1, arg2, ...</code></dt>
 <dd>An die bind Funktion übergebene Werte. Diese Werte werden an die gebundene Funktion überreicht.</dd>
</dl>

<h3 id="Rückgabewert">Rückgabewert</h3>

<p>Eine Kopie der gegebenen Funktion mit dem spezifizierten <strong><code>this</code></strong> Wert und initialen Parametern.</p>

<h2 id="Beschreibung">Beschreibung</h2>

<p>Die <strong>bind()</strong> Funktion erstellt eine neue <strong>gebundene Funktion (BF)</strong>. Eine <strong>BF</strong> ist <strong>ein exotisches Funktionsobjekte</strong> (ein Teil von <strong>ECMAScript 2015</strong>) welches die eigentliche Funktion umhüllt. Das Aufrufen einer <strong>BF</strong> führt zum ausführen der <strong>umhüllten Funktion</strong>. Eine <strong>BF</strong> hat die folgenden internen Eigenschaften:</p>

<ul>
 <li><strong>[[BoundTargetFunction]]</strong> - das umhüllte Funktionsobjekt;</li>
 <li><strong>[[BoundThis]]</strong> - der Wert, der immer als <strong>this</strong> Wert beim Aufruf der umhüllten Funktion genutzt wird.</li>
 <li><strong>[[BoundArguments]]</strong> - eine Liste von Werten, wessen Elemente als erste Argumente bei jedem Aufruf der umhüllten Funktion genutzt werden.</li>
 <li><strong>[[Call]]</strong> - führt Code aus, der mit dem Objekte verbunden ist. Wird über ein Funktionsaufruf ausgeführt. Die Argumente der internen Methode sind ein <strong>this</strong> Wert und eine Liste mit Argumenten, welche beim Aufruf der Funktion übergeben werden.</li>
</ul>

<p>Wenn die gebundene Funktion aufgerufen wird, ruft diese die interne Methode <strong>[[Call]]</strong> auf <strong>[[BoundTargetFunction]]</strong> mit den Argumenten <strong>Call(<em>boundThis</em>, <em>args</em>)</strong> auf. Dabei ist <strong><em>boundThis </em></strong>gleich <strong>[[BoundThis]]</strong> und <em><strong>args </strong></em>gleich <strong>[[BoundArguments]]</strong> gefolgt von den übergebenen Parametern des Funktionsaufrufes.</p>

<p>Eine gebundene Funktion kann zudem mit einen <a href="/de/docs/Web/JavaScript/Reference/Operators/new" title="The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function."><code>new</code></a> Operator erstellt werden: <span id="result_box" lang="de"><span>Das sieht so aus, als ob die Zielfunktion stattdessen konstruiert worden wäre</span></span>. Dar übergebene <strong><code>this</code></strong> Wert wird ignoriert, während die voranstehenden Argumente für die Emulierte Funktion zur Verfügung stehen.</p>

<h2 id="Beispiele">Beispiele</h2>

<h3 id="Erstellen_einer_gebunden_Funktion">Erstellen einer gebunden Funktion</h3>

<p><span id="result_box" lang="de"><span>Die einfachste Verwendung von <code>bind()</code> besteht darin, eine Funktion zu erstellen, die, egal wie sie aufgerufen wird, mit einem <code><strong>this</strong></code> Wert aufgerufen wird. Ein häufiger Fehler für neue JavaScript-Programmierer besteht darin, eine Methode aus einem Objekt zu extrahieren, diese Funktion später aufzurufen und zu erwarten, dass sie das ursprüngliche Objekt als <code><strong>this</strong></code> verwendet (z. B. durch Verwendung dieser Methode in Callback-basiertem Code). Ohne besondere Sorgfalt ist das ursprüngliche Objekt jedoch in der Regel verloren. </span></span><span id="result_box" lang="de"><span>Das Erstellen einer gebundenen Funktion aus der Funktion, die das ursprüngliche Objekt verwendet, löst dieses Problem sauber:</span></span></p>

<pre class="brush: js">this.x = 9;    // this refers to global "window" object here in the browser
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();
// returns 9 - The function gets invoked at the global scope

// Create a new function with 'this' bound to module
// New programmers might confuse the
// global var x with module's property x
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
</pre>

<h3 id="Partiell_gebunden_Funktionen">Partiell gebunden Funktionen</h3>

<p>Der nächste einfache Einsatz von <code>bind()</code> ist das Vordefinieren von Initialparameter einer Funktion. Diese Argumente (wenn welche vorhanden) folgen auf den übergebenen <code>this</code> Wert und Werten am Anfang der Zielfunktion den Parametern hinzugefügt, gefolgt von den Parametern, die der gebunden Funktion übergeben werden, immer wenn die gebunden Funktion aufgerufen wird.</p>

<pre class="brush: js">function list() {
  return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(null, 37);

var list2 = leadingThirtysevenList();
// [37]

var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
</pre>

<h3 id="Mit_setTimeout">Mit <code>setTimeout</code></h3>

<p>Bei {{domxref("window.setTimeout()")}} wird im Standardfall das <code>this</code> Schlüsselwort mit dem {{ domxref("window") }} (oder <code>global</code>) Objekt versehen. Wenn mit Klassenmethoden gearbeitet wird, die es vorgesehen, dass <code>this</code> zu der Klasseninstanz verweist, muss <code>this</code> explizit an die Callback-Funktion gebunden werden, damit die Instanz vorhanden ist.</p>

<pre class="brush: js">function LateBloomer() {
  this.petalCount = Math.floor(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
  window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
  console.log('I am a beautiful flower with ' +
    this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();
// after 1 second, triggers the 'declare' method</pre>

<h3 id="Gebunden_Funktion_mit_einem_Konstruktor">Gebunden Funktion mit einem Konstruktor</h3>

<div class="warning">
<p><strong>Warnung:</strong> Dieses Kapitel demonstriert JavaScript-möglichkeiten und dokumentiert Randfälle der <code>bind()</code> Methode. Die Methoden, die unten gezeigt werden, sind nicht die Besten, um Dinge zu lösen, weshalb sie nicht in einem Produktivsystem eingesetzt werden sollten.</p>
</div>

<p>Gebundene Funktion sind automatisch verfügbar für den Einsatz mit dem {{jsxref("Operators/new", "new")}} Operator, um eine neue Instanz von einer Zielfunktion zu erstellen. Wenn eine gebundene Funktion eingesetzt wird, um einen Wert zu erstellen, wird das unterstützte <code>this</code> Argument ignoriert. Dahingegen werden unterstützte Argumente vor den Konstruktoraufrufe vorgehängt:</p>

<pre class="brush: js">function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function() {
  return this.x + ',' + this.y;
};

var p = new Point(1, 2);
p.toString(); // '1,2'

// not supported in the polyfill below,

// works fine with native bind:

var YAxisPoint = Point.bind(null, 0/*x*/);


var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);

var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'

axisPoint instanceof Point; // true
axisPoint instanceof YAxisPoint; // true
new Point(17, 42) instanceof YAxisPoint; // true
</pre>

<p>Zu beachten ist, dass nichts spezielles getan werden muss, um eine gebundene Funktion mit {{jsxref("Operators/new", "new")}} zu erstellen. <span id="result_box" lang="de"><span>Die Folge ist, dass man nichts Besonderes tun muss, um eine gebundene Funktion zu erzeugen, die einfach aufgerufen werden kann, selbst wenn es gewollt ist, dass die gebundene Funktion nur mit </span></span>{{jsxref("Operators/new", "new")}} <span lang="de"><span>aufgerufen wird:</span></span></p>

<pre class="brush: js">// Example can be run directly in your JavaScript console
// ...continuing from above

// Can still be called as a normal function
// (although usually this is undesired)
YAxisPoint(13);

emptyObj.x + ',' + emptyObj.y;
// &gt;  '0,13'
</pre>

<p>Wenn es gewünscht ist, dass der Einsatz von gebundenen Funktion nur mit {{jsxref("Operators/new", "new")}} oder einem einfachen Aufruf sein soll, so muss die Zielfunktion diese Einschränkung erzwingen.</p>

<h3 id="Kurzformen_erstellen">Kurzformen erstellen</h3>

<p><code>bind()</code> ist nützlich in fällen, in denen man kurzformen erstellen will, bei denen ein spezifischer <strong><code>this</code></strong> vorhanden sein soll.</p>

<p>Nimmt man zum Beispiel {{jsxref("Array.prototype.slice")}}, welche man zum Konvertieren von Array ähnlichen Objekte zu einem richtigen Array einsetzen mögliche, dann kann man eine Kurzform wie diese erstellen:</p>

<pre class="brush: js">var slice = Array.prototype.slice;

// ...

slice.apply(arguments);
</pre>

<p>Mit <code>bind()</code>, kann dieses vereinfacht werden. Im folgenden Codestück ist <code>slice</code> eine gebunden Funktion zu der {{jsxref("Function.prototype.apply()", "apply()")}} Funktion von {{jsxref("Function.prototype")}} mit dem <strong><code>this</code></strong> Wert auf der {{jsxref("Array.prototype.slice()", "slice()")}} Funktion von {{jsxref("Array.prototype")}}. Das bedeutet, dass der zusätzliche Aufruf von <code>apply()</code> nicht nötig ist:</p>

<pre class="brush: js">// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);

// ...

slice(arguments);
</pre>

<h2 id="Polyfill">Polyfill</h2>

<p>Wenn die <code>bind()</code> Funktion nicht vorhanden ist, kann ein Großteil der Funktionalität mit trotzdem hinzugefügt werden, indem der folgende Quelltext am Anfang des Skriptes hinzugefügt wird.</p>

<pre class="brush: js">if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    if (this.prototype) {
      // Function.prototype doesn't have a prototype property
      fNOP.prototype = this.prototype;
    }
    fBound.prototype = new fNOP();

    return fBound;
  };
}
</pre>

<p><span id="result_box" lang="de"><span>Einige der vielen Unterschiede (es kann durchaus andere geben, weil bei dieser Liste nicht auf Vollständig geachtet wurde) zwischen diesem Algorithmus und dem angegebenen Algorithmus sind:</span></span></p>

<ul>
 <li>Die partielle Implementierung basiert auf der {{jsxref("Array.prototype.slice()")}}, {{jsxref("Array.prototype.concat()")}}, {{jsxref("Function.prototype.call()")}} und {{jsxref("Function.prototype.apply()")}} Methode, um die Originalen Werte zu erhalten.</li>
 <li>Die partielle Implementierung erstellt Funktionen, die keinen unveränderbar {{jsxref("Function.caller", "caller")}} haben und eine <code>arguments</code> Eigenschaft die einen {{jsxref("Global_Objects/TypeError", "TypeError")}} auslöst, wenn get, set oder deletion benutzt wird. (Dieses kann hinzugefügt werden, wenn die Implementierung {{jsxref("Object.defineProperty")}} unterstützt oder partiell implementiert [ohne das Löschverhalten], wenn die Implementierung {{jsxref("Object.defineGetter", "__defineGetter__")}} und {{jsxref("Object.defineSetter", "__defineSetter__")}} Erweiterungen unterstützt.)</li>
 <li>Die partielle Implementierung erstellt Funktionen, die einen <code>prototype</code> Eigenschaft haben. (Normale gebundene Funktionen haben keine)</li>
 <li>Die partielle Implementierung erstellt gebundene Funktionen mit der {{jsxref("Function.length", "length")}} Eigenschaft, die nicht mit ECMA-262 übereinstimmt: Sie erstellt Funkton mit <code>length</code> 0, während bei der vollständigen Implementierung die Länge von der Zielfunktion und der Anzahl von vordefinierten Parametern abhängt und daher eine andere Länge zurück geben kann.</li>
</ul>

<p>Wenn diese partielle Implementierung eingesetzt wird, <strong>muss man davon ausgehen, dass dessen Verhalten von dem in ECMA-262 in der 5. Auflage unterscheidet!</strong> Mit etwas Vorsicht (und vielleicht kleinen Modifizierungen für spezielle Anforderungen) kann diese partielle Implementierung eine gute Übergangslösung für die Zeit sein, in der <code>bind()</code> noch nicht in allen Umgebungen unterstützt wird.</p>

<p>Auf <a href="https://github.com/Raynos/function-bind">https://github.com/Raynos/function-bind</a> könnte es eine gründlichere Lösung geben!</p>

<h2 id="Spezifikationen">Spezifikationen</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Spezifikation</th>
   <th scope="col">Status</th>
   <th scope="col">Kommentar</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.3.4.5', 'Function.prototype.bind')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Initiale Definition. Implementiert in JavaScript 1.8.5.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-function.prototype.bind', 'Function.prototype.bind')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-function.prototype.bind', 'Function.prototype.bind')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="Browserkompatibilität">Browserkompatibilität</h2>

<div>


<p>{{Compat("javascript.builtins.Function.bind")}}</p>
</div>

<h2 id="Siehe_auch">Siehe auch</h2>

<ul>
 <li>{{jsxref("Function.prototype.apply()")}}</li>
 <li>{{jsxref("Function.prototype.call()")}}</li>
 <li>{{jsxref("Functions", "Functions", "", 1)}}</li>
</ul>