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
|
---
title: Getter
slug: Web/JavaScript/Reference/Functions/get
tags:
- ECMAScript 2015
- ECMAScript 5
- Functions
- JavaScript
- Language feature
translation_of: Web/JavaScript/Reference/Functions/get
---
<div>{{jsSidebar("Functions")}}</div>
<p>Die <strong><code>get</code></strong> Syntax bindet eine Objekteigenschaft an eine Funktion welche aufgerufen wird, wenn die Eigenschaft abgefragt wird.</p>
<div>{{EmbedInteractiveExample("pages/js/functions-getter.html")}}</div>
<h2 id="Syntax">Syntax</h2>
<pre class="syntaxbox">{get <var>prop</var>() { ... } }
{get [<var>expression</var>]() { ... } }</pre>
<h3 id="Parameter">Parameter</h3>
<dl>
<dt><code>prop</code></dt>
<dd>Der Name der Eigenschaft, die an die gegebene Funktion gebunden wird.</dd>
<dt><code><var>expression</var></code></dt>
<dd>Beginnend mit ECMAScript 2015, kann auch ein Ausdruck für einen berechneten Eigenschaftsnamen genutzt werden, der an die Funktion gebunden wird.</dd>
</dl>
<h2 id="Beschreibung">Beschreibung</h2>
<p>Manchmal ist es wünschenswert, den Zugriff auf eine Eigenschaft zuzulassen, die einen dynamisch berechneten Wert zurückgibt oder man möchten den Status einer internen Variablen widerspiegeln, ohne dass explizite Methodenaufrufe erforderlich sind. In JavaScript kann dieses mit einem <em>getter</em> erreicht werden.</p>
<p>Es ist nicht möglich, dass ein Getter gleichzeitig an eine Eigenschaft gebunden ist und diese Eigenschaft tatsächlich einen Wert enthält, obwohl es möglich ist, einen Getter und einen Setter in Verbindung zu verwenden, um einen Pseudoeigenschaftstyp zu erstellen.</p>
<p>Folgendes ist zu beachten, wenn die <code>get</code> Syntax verwendet wird:</p>
<ul>
<li>Sie kann ein Bezeichner haben, welche entweder eine Zahl oder ein String ist.</li>
<li>Sie muss exakt null Parameter haben (siehe <a class="external" href="http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/" rel="external nofollow">Incompatible <abbr title="ECMAScript 5th edition">ES5</abbr> change: literal getter and setter functions must now have exactly zero or one arguments</a> für mehr Informationen);</li>
<li>Es darf nicht in einem Objektliteral mit einem anderen <code>get</code> oder Dateneintrag für die gleiche Eigenschaft benutzt werden (<code>{ get x() { }, get x() { } }</code> und <code>{ x: ..., get x() { } }</code> sind verboten).</li>
</ul>
<h2 id="Beispiele">Beispiele</h2>
<h3 id="Definition_eines_Getters_in_einem_neuen_Objekt_in_der_Objektinitialisierung">Definition eines Getters in einem neuen Objekt in der Objektinitialisierung</h3>
<p>Folgendes erstellt eine Pseudoeigenschaft <code>latest</code> für das Objekt <code>obj</code>, welche dan letzte Arrayeintrag von <code>log</code> zurückgibt.</p>
<pre class="brush: js">const obj = {
log: ['example','test'],
get latest() {
if (this.log.length === 0) return undefined;
return this.log[this.log.length - 1];
}
}
console.log(obj.latest); // "test".
</pre>
<p>Zu beachten ist, dass die Zuweisung eines Wertes auf <code>latest</code> keine Änderung bewirkt.</p>
<h3 id="Löschen_eines_Getters_mit_dem_delete_Operator">Löschen eines Getters mit dem <code>delete</code> Operator</h3>
<p>Wenn ein Getter gelöscht werden soll, kann einfach {{jsxref("Operators/delete", "delete")}} benutzt werden:</p>
<pre class="brush: js">delete <var>obj</var>.latest;
</pre>
<h3 id="Definition_eines_Getter_auf_einem_existierenden_Objektes_mit_defineProperty">Definition eines Getter auf einem existierenden Objektes mit <code>defineProperty</code></h3>
<p>Um einem Getter später zu einem existierenden Objekt hinzuzufügen, kann jederzeit {{jsxref("Object.defineProperty()")}} benutzt werden.</p>
<pre class="brush: js">const o = {a: 0};
Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });
console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)</pre>
<h3 id="Einen_berechneten_Eigenschaftnamen_benutzen">Einen berechneten Eigenschaftnamen benutzen</h3>
<pre class="brush: js">const expr = 'foo';
const obj = {
get [expr]() { return 'bar'; }
};
console.log(obj.foo); // "bar"</pre>
<h3 id="Intelligente_Selbstüberschreibende_Lazy_Getter">Intelligente / Selbstüberschreibende / Lazy Getter</h3>
<p>Mit Gettern kann eine Eigenschaft eines Objekts <em>definiert</em> werden, wobei der Wert der Eigenschaft nicht <em>berechnen</em> wird, bis auf die Eigenschaft zugegriffen wird. Ein Getter verschiebt die Kosten für die Berechnung des Werts auf den Zeitpunkt des Zugriffs. Wenn der der Getter nie benötigt wird, fallen nie Kosten an.</p>
<p>Eine weitere Optimierungstechnik, um die Berechnung eines Eigenschaftswerts zu verzögern und ihn für einen späteren Zugriff zwischenzuspeichern, sind <strong>intelligente (oder "<a href="https://de.wikipedia.org/wiki/Memoisation">memoisierte</a>") Getter</strong>. Der Wert wird berechnet, wenn der Getter das erste Mal aufgerufen wird und wird dann zwischengespeichert, damit nachfolgende Zugriffe den zwischengespeicherten Wert zurückgeben, ohne ihn neu zu berechnen. Dies ist in den folgenden Situationen nützlich:</p>
<ul>
<li>Wenn die Berechnung eines Eigenschaftswerts teuer ist (erfordert viel RAM- oder CPU-Zeit, erzeugen von Worker-Threads, ruft eine Remote-Datei ab usw.).</li>
<li>Wenn der Wert gerade nicht benötigt wird. Er wird später verwendet oder in einigen Fällen wird er überhaupt nicht verwendet.</li>
<li>Wenn er verwendet wird, wird mehrmals darauf zugegriffen und er ist nicht erforderlich, den Wert neu zu berechnen, da er nie geändert oder nicht neu berechnet wird.</li>
</ul>
<div class="note">
<p>Das bedeutet, dass keine verzögerten Getter für eine Eigenschaft verwenden werden sollten, deren Wert sich voraussichtlich ändern wird, weil der Getter den Wert nicht neu berechnet.</p>
</div>
<p>Im folgenden Beispiel hat das Objekt einen Getter als eigene Eigenschaft. Beim Abrufen der Eigenschaft wird die Eigenschaft aus dem Objekt entfernt und erneut hinzugefügt, diesmal jedoch implizit als Dateneigenschaft. Abschließend wird der Wert zurückgegeben.</p>
<pre class="brush: js">get notifier() {
delete this.notifier;
return this.notifier = document.getElementById('bookmarked-notification-anchor');
},</pre>
<p>Für Firefox Code sollte zusätzlich das <code>XPCOMUtils.jsm</code> Code Modul angeschaut werden, welches die <code><a href="/de/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter()">defineLazyGetter()</a></code> Funktion definiert.</p>
<h3 id="get_vs._defineProperty"><code>get</code> vs. <code>defineProperty</code></h3>
<p>Das <code>get</code> Schlüsselwort und {{jsxref("Object.defineProperty()")}} haben ähnliche Ergebnisse. Es gibt einen kleinen Unterschied zwischen beiden, wenn {{jsxref("classes")}} eingesetzt werden.</p>
<p>Wenn <code>get</code> eingesetzt wird, wird die Eigenschaft im Instnaz-Prototyp definiert, während beim Einsatz von {{jsxref("Object.defineProperty()")}} die Eigenschaft auf der Instanz definiert wird.</p>
<pre class="brush: js">class Example {
get hello() {
return 'world';
}
}
const obj = new Example();
console.log(obj.hello);
// "world"
console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
// undefined
console.log(
Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(obj), 'hello'
)
);
// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }</pre>
<h2 id="Spezifikationen">Spezifikationen</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Spezifikation</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}</td>
</tr>
</tbody>
</table>
<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
<p>{{Compat("javascript.functions.get")}}</p>
<h2 id="Siehe_auch">Siehe auch</h2>
<ul>
<li><a href="/de/docs/Web/JavaScript/Reference/Functions/set">setter</a></li>
<li>{{jsxref("Operators/delete", "delete")}}</li>
<li>{{jsxref("Object.defineProperty()")}}</li>
<li>{{jsxref("Object.defineGetter", "__defineGetter__")}}</li>
<li>{{jsxref("Object.defineSetter", "__defineSetter__")}}</li>
<li><a href="/de/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">Defining Getters and Setters</a> im JavaScript Guide</li>
</ul>
|