aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/operators/this/index.html
blob: d9c36c61d605f1a901084b75c170fe70b395cb54 (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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
---
title: this
slug: Web/JavaScript/Reference/Operators/this
tags:
  - JavaScript
  - Operator
  - Primary Expressions
  - Reference
translation_of: Web/JavaScript/Reference/Operators/this
---
<div>{{jsSidebar("Operators")}}</div>

<p>Das <strong>this Schlüsselwort einer Funktion</strong> in JavaScript verhält sich verglichen mit anderen Sprachen ein bisschen anders. Es gibt zudem Unterschiede zwischen dem <a href="/de/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict Modus</a> und nicht strict Modus.</p>

<p>In den meisten Fällen ist der Wert von <code>this</code> der Aufrufer der Funktion. Der Wert kann nicht während der Ausführung zugewiesen werden und kann sich jedes Mal, wenn die Funktion aufgerufen wird unterscheiden. ES5 führte die <code><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bind</a></code> Methode ein, <a href="#Die_bind_Methode">um den Wert vom <code>this</code> einer Funktion zu setzen (egal, wie sie aufgerufen wird)</a>. ECMAScript 2015 hat die <a href="/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Pfeilfunktionen</a> implementiert, die kein eigenes <code>this</code> besitzt (<code>this</code> verweist auf das <code>this</code> des umschließenden Ausführungskontextes).</p>

<div>{{EmbedInteractiveExample("pages/js/expressions-this.html")}}</div>



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

<pre class="syntaxbox">this</pre>

<h2 id="Globaler_Kontext">Globaler Kontext</h2>

<p>Im globalen Ausführungskontext (außerhalb jeder Funktion), referenziert <code>this</code> auf das globale Objekt, egal ob im strict Modus oder nicht.</p>

<pre class="brush:js">// Im Webbrowser ist das window Objekt das globale Objekt:
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b);  // "MDN"
console.log(b);         // "MDN"
</pre>

<h2 id="Funktionskontext">Funktionskontext</h2>

<p>Innerhalb einer Funktion hängt der Wert von <code>this</code> davon ab, wie die Funktion aufgerufen wird.</p>

<h3 id="Einfacher_Aufruf">Einfacher Aufruf</h3>

<p>Weil der folgende Code nicht im <a href="/de/docs/Web/JavaScript/Reference/Strict_mode">strict Modus</a> ist und weil <code>this</code> nicht vom Aufruf gesetzt wird, referenziert <code>this</code> das globale Objekt, welches in einem Browser <code>window</code> ist.</p>

<pre class="brush: js">function f1(){
  return this;
}

// In einem Browser:
f1() === window; // true

// In Node:
f1() === global; // true</pre>

<p>Im strict Modus bleibt der Wert von <code>this</code> jedoch auf dem Wert, auf den er beim Eingeben des Ausführungskontextes festgelegt wurde. Im folgenden Fall wird dies standardmäßig auf <code>undefined</code> sein:</p>

<pre class="brush:js">function f2(){
  "use strict"; // see strict mode
  return this;
}

f2() === undefined; // true
</pre>

<p>Wenn <code>this</code> im <strong>strict Modus</strong> nicht vom Ausführungskontext definiert wird, bleibt dieser <code>undefined</code>.</p>

<div class="note">Im zweiten Beispiel sollte <code>this</code> <code><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code> sein, weil <code>f2</code> direkt und nicht als eine Methode oder Eigenschaft eines Objektes (z. B. <code>window.f2()</code>) aufgerufen wird. Diese Funktionalität war noch nicht in allen Browsern implementiert, als der Support für den strict Modus gestartet wurde. Als Folge, gaben diese fälschlicherweise das <code>window</code> Objekt zurück.</div>

<p>Um den Wert von <code>this</code> von einem in den anderen Kontext zu überführen, benutzt man <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a> oder <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a><strong>:</strong></p>

<pre class="brush: js">// Ein Objekt kann als erstes Argument beim Aufruf von call oder apply benutzt werden
// welches an den Aufruf gebunden wird.
var obj = {a: 'Custom'};

// Dieses Objekt wird auf dem globalen Objekt definiert
var a = 'Global';

function whatsThis() {
  return this.a; // Der Wert von this hängt davon ab, wie die Funktion aufgerufen wird.
}

whatsThis();          // 'Global'
whatsThis.call(obj);  // 'Custom'
whatsThis.apply(obj); // 'Custom'</pre>

<p>Wenn eine Funktion das <code>this</code> Schlüsselwort im Körper verwendet, kann dessen Wert an ein Objekt gebunden werden, wenn die <code><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a></code> oder <code><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a></code> Methode genutzt wird, die alle Funktion von <code>Function.prototype</code> erben.</p>

<pre class="brush: js">function add(c, d) {
  return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

// Der erste Parameter ist das Objekt, welches als
// 'this' genutzt wird. Alle weiteren Parameter werden als
// Argumente für den Funktionsaufruf benutzt.
add.call(o, 5, 7); //16

// Der erste Parameter ist das Objekt, welches als
// 'this' genutzt wird. Der zweite Parameter ist ein Array.
// Dessen Elemente werden als Argumente für den Funktionsaufruf benutzt.
add.apply(o, [10, 20]); // 34</pre>

<p>Bei <code>call</code> und <code>apply</code> ist zu beachten, dass wenn der für <code>this</code> übergebene Wert kein Objekt ist, wird dieser mit der internen Operation <code>ToObject</code> zu einem Objekt konvertiert. Ist der übergebene Wert ein primitiver Typ wie <code>7</code> oder <code>'foo'</code>, wird dieser mit einem zugehörigen Konstruktor zu einem Objekt konvertiert, so dass die primitive Nummer <code>7</code> mit <code>new Number(7)</code> und <code>'foo'</code> mit <code>new String('foo')</code> zu ein Objekt konvertiert wird.</p>

<pre class="brush: js">function bar() {
  console.log(Object.prototype.toString.call(this));
}

bar.call(7);     // [object Number]
bar.call('foo'); // [object String]</pre>

<h3 id="Die_bind_Methode">Die <code>bind</code> Methode</h3>

<p>ECMAScript 5 hat <code><a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind</a></code> eingeführt. Der Aufruf von <code>f.bind(someObject)</code> erstellt eine neue Funktion mit dem selben Körper und Gültigkeitsbereich von <code>f</code>, aber <code>this</code> unterscheidet sich zur original Funktion. In der neuen Funktion ist <code>this</code> permanent mit dem Parameter von <code>bind</code> gebunden, egal wie die Funktion benutzt wird.</p>

<pre class="brush:js">function f(){
  return this.a;
}

var g = f.bind({a: 'azerty'});
console.log(g()); // azerty

var h = g.bind({a: 'yoo'}); // bind funktioniert nur einmal!
console.log(h()); // azerty

var o = {a: 37, f: f, g: g, h: h};
console.log(o.f(), o.f(), o.g(), o.h()); // 37, 37, azerty, azerty</pre>

<h3 id="Pfeilfunktionen">Pfeilfunktionen</h3>

<p>In <a href="/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Pfeilfunktionen</a>, wird <code>this</code> auf das <code>this</code> des umschließenden lexikalischen Kontextes gesetzt. In globalem Code wird es auf das globale Objekt gesetzt.</p>

<pre class="brush: js">var globalObject = this;
var foo = (() =&gt; this);
console.log(foo() === globalObject); // true</pre>

<div class="note">
<p>Hinweis: Wenn das this Argument von call, bind oder apply auf einer Pfeilfunktion benutzt werden, wird dieser ignoriert. Man kann dem Aufruf weitere Argumente hinzufügen, das erste Argument (thisArg) sollte aber null sein.</p>
</div>

<pre class="brush: js">// Aufruf als Methode eines Objektes
var obj = {foo: foo};
console.log(obj.foo() === globalObject); // true

// Versuch this mit <code class="language-js">call</code> zu setzen
console.log(foo.call(obj) === globalObject); // true

// Versuch this mit bind zu setzen
foo = foo.bind(obj);
console.log(foo() === globalObject); // true</pre>

<p>Es ist egal, auf welches <code>this</code> für <code>foo</code> beim erstellen gesetzt wurde (im Beispiel oben das globale Objekt). Das selbe gilt für Pfeilfunktionen, die in einer anderen Funktion erstellt werden: ihr <code>this</code> wird auf das <code>this</code> des äußeren Ausführungskontext gesetzt.</p>

<pre class="brush: js">// Erstellt obj mit einer Methode bar, die eine Funktion zurück gibt,
// die ihr this zurück gibt. Die zurückgegebene  Funktion wird als
// Pfeilfunktion erstellt, so dass ihr this permanent an die umschließende
// Funktion gebunden ist. Der Wert von bar kann im Aufruf festgelegt werden,
// der wiederum den Wert der zurückgegebenen Funktion festlegt.
var obj = { bar : function() {
                    var x = (() =&gt; this);
                    return x;
                  }
          };

// Der Aufruf von bar als Methode von obj, setzt das this auf obj,
// Weist eine Referenz der zurückgegebenen Funktion fn zu.
var fn = obj.bar();

// Aufruf von fn ohne this zu setzen, wird normalerweise zum
// golbalen Objekt oder undefined im strict Modus führen.
console.log(fn() === obj); // true

// Aber achtung, wenn man die Methode von obj referenziert ohne sie aufzurufen
var fn2 = obj.bar;
// Wenn dann die Pfeilfunktion aufgerufen wird, ist this gleich dem globalen Objekt,
// weil es dem this von bar folgt.
console.log(fn2()() == window); // true
</pre>

<p>Im oberen Beispiel, gibt die Funktion (nennen wir sie anonyme Funktion A), die zu <code>obj.bar</code> zugewiesen ist, gibt eine andere Funktion (nennen wir sie anonyme Funktion B) zurück, die als Pfeilfunktion erstellt wurde. Als Ergebnis ist das <code>this</code> von B permanent das <code>this</code> von <code>obj.bar</code> (Funktion A) beim Aufruf. Wenn die zurückgegebene Funktion (Funktion B) aufgerufen wird, ist der <code>this</code> Wert immer der, der er initial war. Im obigen Beispielcode ist das <code>this</code> der Funktion B auf das <code>this</code> der Funktion A gesetzt, welches obj ist, so dass es auf <code>obj</code> gesetzt bleibt, während hingegen normalerweise <code>this</code> <code>undefined</code> oder das globale Objekt (oder jede andere Methode wie im vorherigen Beispiel im globalen Ausführungskontext) ist.</p>

<h3 id="Alseine_Objektmethode">Alseine Objektmethode</h3>

<p>Wenn eine Funktion als Methode eines Objektes aufgerufen wird, hat <code>this</code> eine Referenz auf das Objekt, auf dem die Methode aufgerugen wurde.</p>

<p>Im folgenden Beispiel ist <code>this</code> innerhalb der Funktion auf <code>o</code> gebunden, wenn <code>o.f()</code> ausgeführt wird.</p>

<pre class="brush:js">var o = {
  prop: 37,
  f: function() {
    return this.prop;
  }
};

console.log(o.f()); // 37
</pre>

<p>Zu beachten ist, dass dieses Verhalten nicht davon beeinflusst ist wie und wo die Funktion definiert ist. Im folgenden Beispiel definierten wir eine Inlinefunktion <code>f</code> als Eigenschaft von <code>o</code>. Man könnte auch einfach die Funktion zuerst definieren und diese dann <code>o.f</code> zuweisen. Dieses hat das selbe Ergebnis zur Folge:</p>

<pre class="brush:js">var o = {prop: 37};

function independent() {
  return this.prop;
}

o.f = independent;

console.log(o.f()); // logs 37
</pre>

<p>Das demonstriert, dass es nur wichtig ist, dass die Funktion als Eigenschaft <code>f</code> des Objektes <code>o</code> aufgerufen wurde.</p>

<p>Genauso ist die <code>this</code> Bindung nur von der unmittelbaren Mitgliederreferent beeinflusst. Im folgenden Beispiel, wenn die Funktion aufgerufen wird, wird diese als Methode <code>g</code> des Objektes <code>o.b</code> aufgerufen. Während der Ausführung referenziert <code>this</code> in der Funktion <code>o.b</code>. Der Fakt, dass das Objekt selbst eine Eigenschaft von <code>o</code> ist, hat keine Konsequenz, nur die unmittelbare Referenz ist wichtig.</p>

<pre class="brush:js">o.b = {g: independent, prop: 42};
console.log(o.b.g()); // logs 42
</pre>

<h4 id="this_auf_der_Objektprototypenkette"><code>this</code> auf der Objektprototypenkette</h4>

<p>Das selbe gilt für Methoden, die irgendwo auf der Objektprototypenkette definiert werden. Wenn die Methode auf einer Objektprototypenkette ist, referenziert <code>this</code> zu dem Objekte, auf dem die Methode aufgerufen wurde, so als währe die Methode auf dem Objekt.</p>

<pre class="brush:js">var o = {f: function() { return this.a + this.b; }};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5
</pre>

<p>In diesem Beispiel hat das Objekt, welches der Variablen <code>p</code> zugewiesen wird, nicht ihre eigene <code>f</code> Eigenschaft, es erbt sie von seinem Prototyp. Aber es spielt keine Rolle, ob die Suche nach <code>f</code> eventuell eine Eigenschaft/Methode auf dem Objekt <code>o</code> findet; Die Suche begann als eine Referenz zu <code>p.f</code>, so hat <code>this</code> in der Funktion eine Referenz zu dem Objekt <code>p</code>. Weil <code>f</code> als Methode von <code>p</code> aufgerufen wurde, referenziert <code>this</code> <code>p</code>. Dieses ist eine interessante Funktion von JavaScripts's Prototypenvererbung.</p>

<h4 id="this_mit_Gettern_oder_Settern"><code>this</code> mit Gettern oder Settern</h4>

<p>Wieder das selbe gilt für für Funktionen, die als Getter oder Setter aufgerufen werden. Eine Funktion, die als Getter oder Setter benutzt wird, hat <code>this</code> zu dem Objekt gebunden, auf dem der Getter oder Setter aufgerufen wurde.</p>

<pre class="brush:js">function sum(){
  return this.a + this.b + this.c;
}

var o = {
  a: 1,
  b: 2,
  c: 3,
  get average(){
    return (this.a + this.b + this.c) / 3;
  }
};

Object.defineProperty(o, 'sum', {
    get: sum, enumerable:true, configurable:true});

console.log(o.average, o.sum); // logs 2, 6
</pre>

<h3 id="Als_ein_Konstruktor">Als ein Konstruktor</h3>

<p>Wenn eine Funktion als Konstruktor verwendet wird (mit dem <code><a href="/de/docs/Web/JavaScript/Reference/Operators/new">new</a></code> Schlüsselwort), ist <code>this</code> an das neu erstellte Objekt gebunden.</p>

<div class="note">
<p>Weil der Standard für einen Konstruktor besagt, dass das Objekt, welches auf <code>this</code> referenziert, zurückgegeben wird, kann stattdessen ein anderes Objekt zurückgegeben werden (wenn der Rückgabewert kein Objekt ist, wird <code>this</code> zurückgegeben).</p>
</div>

<pre class="brush:js">/*
 * Constructors work like this:
 *
 * function MyConstructor(){
 *   // Actual function body code goes here.
 *   // Create properties on |this| as
 *   // desired by assigning to them.  E.g.,
 *   this.fum = "nom";
 *   // et cetera...
 *
 *   // If the function has a return statement that
 *   // returns an object, that object will be the
 *   // result of the |new| expression.  Otherwise,
 *   // the result of the expression is the object
 *   // currently bound to |this|
 *   // (i.e., the common case most usually seen).
 * }
 */

function C(){
  this.a = 37;
}

var o = new C();
console.log(o.a); // logs 37


function C2(){
  this.a = 37;
  return {a:38};
}

o = new C2();
console.log(o.a); // logs 38
</pre>

<p>Im letzen Beispiel (<code>C2</code>) wird das gebundene <code>this</code> Objekt verworfen, weil während des Erstellens ein anderes Objekt zurückgegeben wird. (Das macht das Statement <code>this.a = 37;</code> zu todem Code. Er ist nicht ganz tod, weil er ausgeführt wird, aber entfernt werden kann ohne einen Effekt zu haben.)</p>

<h3 id="Als_ein_DOM_Eventhandler">Als ein DOM Eventhandler</h3>

<p>Wenn eine Funktion als Eventhandler genutzt wird, wird sein <code>this</code> auf das Element, welches das Event feuert, gesetzt (manche Browser folgen dieser Konvention nicht für das dynamische hinzufügen von Methoden nicht über <code>addEventListener</code>).</p>

<pre class="brush:js">// When called as a listener, turns the related element blue
function bluify(e){
  // Always true
  console.log(this === e.currentTarget);
  // true when currentTarget and target are the same object
  console.log(this === e.target);
  this.style.backgroundColor = '#A5D9F3';
}

// Get a list of every element in the document
var elements = document.getElementsByTagName('*');

// Add bluify as a click listener so when the
// element is clicked on, it turns blue
for(var i=0 ; i&lt;elements.length ; i++){
  elements[i].addEventListener('click', bluify, false);
}</pre>

<h3 id="In_einem_Inlineeventhandler">In einem Inlineeventhandler</h3>

<p>Wenn Code in einem inline <a href="/de/docs/Web/Guide/Events/Event_handlers">on-event Handler</a> aufgerufen wird, wird <code>this</code> auf das DOM Element gesetzt, auf dem der Listener aufgerufen wird:</p>

<pre class="brush:js">&lt;button onclick="alert(this.tagName.toLowerCase());"&gt;
  Show this
&lt;/button&gt;
</pre>

<p>Der obere Alert zeigt <code>button</code>. Zu beachten ist, dass nur bei äußerem Code das <code>this</code> so gesetzt wird:</p>

<pre class="brush:js">&lt;button onclick="alert((function(){return this}()));"&gt;
  Show inner this
&lt;/button&gt;
</pre>

<p>In diesem Fall ist das <code>this</code> der inneren Funktion nicht gesetzt, so dass das globale/window Objekt zurückgegeben wird (z. B. das Standardobjekt in nicht strict Modus, wo <code>this</code> nicht vom Aufruf gesetzt wird).</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('ESDraft', '#sec-this-keyword', 'The this keyword')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-this-keyword', 'The this keyword')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.1.1', 'The this keyword')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES3', '#sec-11.1.1', 'The this keyword')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES1', '#sec-11.1.1', 'The this keyword')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>Erste Definition. Implementiert in JavaScript 1.0.</td>
  </tr>
 </tbody>
</table>

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



<p>{{Compat("javascript.operators.this")}}</p>

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

<ul>
 <li><a href="/de/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode">Strict Modus</a></li>
 <li><a href="http://rainsoft.io/gentle-explanation-of-this-in-javascript/">Gentle explanation of 'this' keyword in JavaScript</a></li>
</ul>