aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/equality_comparisons_and_sameness/index.html
blob: c8a2064eabf2431c1762f9881ee6b0a300d0d8f5 (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
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
---
title: Vergleiche auf Gleichheit und deren Verwendung
slug: Web/JavaScript/Equality_comparisons_and_sameness
translation_of: Web/JavaScript/Equality_comparisons_and_sameness
original_slug: Web/JavaScript/Vergleiche_auf_Gleichheit_und_deren_Verwendung
---
<div>{{jsSidebar("Intermediate")}}</div>

<div class="summary">
<p>JavaScript bietet drei verschiedene Operationen an, um Werte zu vergleichen:</p>

<ul>
 <li>strikte Gleichheit (oder "triple equals" or "identity") mit <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Identity">===</a>,</li>
 <li>lose Gleichheit ("double equals") mit <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality">==</a>,</li>
 <li>und <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> (neu in ECMAScript 2015).</li>
</ul>

<p>Die Wahl der Operation hängt von der Art des gewünschten Vergleichs auf Gleichheit ab.</p>
</div>

<p>Kurz gesagt nimmt double equals eine Typkonvertierung der Operanden vor, bevor der Vergleich der Werte gemacht wird. Bei triple equals werden die Werte ohne vorherige Typkonvertierung miteinander verglichen. Wenn sich die Datentypen der beiden Operanden unterscheiden liefert triple equals immer <code>false</code> zurück. <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> verhält sich wie triple equals und bietet darüber hinaus eine spezielle Behandlung für <code>NaN</code> und <code>-0</code> und <code>+0</code> an. <code>-0</code> und <code>+0</code> sind für <code>Object.is</code> ungleich während <code>Object.is(NaN, NaN) true</code> ist. Laut IEEE 754 ergibt ein Vergleich von zwei <code>NaN</code> mit double equals oder triple equals <code>false</code>. Diese drei Operationen unterscheiden sich ihrere Behandlung von primitiven Datentypen. Es wird nicht geprüft, ob die beiden Operanden konzeptionell diesselbe Struktur besitzen. Für die nichtprimitiven Objekte x und y, welche diesselbe Struktur besitzen aber zwei unterschiedliche Objekte sind, ergeben die drei Operationen <code>false</code>.</p>

<h2 id="Strikte_Gleichheit_mit">Strikte Gleichheit mit <code>===</code></h2>

<p>Strikte Gleichheit prüft zwei Werte auf Gleichheit. Keiner der Werte wird vor dem Vergleich implizit konvertiert. Wenn die Werte verschiedene Datentypen haben, werden die Werte als ungleich betrachtet. Anderenfalls, wenn die Werte denselben Datentyp haben und keine Zahlen sind, werden sie als gleich betrachtet, solange sie denselben Wert haben. Wenn beide Werte Zahlen sind, werden sie als gleich betrachtet, solange beide nicht NaN sind und denselben Wert haben oder der eine Wert +0 und der andere Wert -0 ist.</p>

<pre class="brush: js">var num = 0;
var obj = new String("0");
var str = "0";
var b = false;

console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true

console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
</pre>

<p>Strikte Gleichheit ist fast immer die am meisten geeignete Vergleichsoperation. Für alle Werte, die keine Zahlen sind, verwendet sie die naheliegende Semantik: ein Wert ist nur mit sich selbst gleich. Für Zahlen kommt eine leicht unterschiedliche Semantik zum Einsatz, da zwei Grenzfälle berücksichtigt werden müssen.  Im ersten Grenzfall kann die Zahl 0 als Gleitkommazahl ein positives oder negatives Vorzeichen haben. Dies kann zur Repräsentation von bestimmten mathematischen Lösungen nützlich sein. Da aber in den meisten Situationen nicht zwischen +0 und -0 unterschieden wird, behandelt die strikte Gleichheit diese zwei Werte als gleich. Der zweite Grenzfall ergibt sich dadruch, dass Gleitkommazahlen einen keine-Zahl Wert haben, <code>NaN</code> (not-a-number). Dadurch können Lösungen für schlecht definierte mathematische Probleme dargestellt werden (z.B.: negativ unendlich plus positiv undendlich). Strikte Gleichheit behandelt <code>NaN</code> als ungleich zu jedem anderen Wert und sich selbst. Der einzige Fall, in dem <code>(x !== x)</code> <code>true</code> ergibt, ist, wenn <code>x</code> den Wert <code>NaN</code> hat.</p>

<h2 id="Lose_Gleichheit_mit">Lose Gleichheit mit <code>==</code></h2>

<p>Lose Gleichheit vergleicht zwei Werte auf deren Gleichheit, <em>nachdem</em> beide zu demselben Datentyp konvertiert wurden. Nach der Konvertierung (ein oder beide Werte können konvertiert werden) wird der finale Vergleich wie bei <code>===</code> ausgeführt.  Lose Gleichheit ist <em>symmetrisch</em>: <code>A == B</code> hat immer dieselbe Semantik wie <code>B == A</code> für alle Werte von <code>A</code> und <code>B</code>.</p>

<p>Der Vergleich auf Gleichheit wird wie folgt für Operanden mit den verschiedenen Datentypen ausgeführt:</p>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="row"> </th>
   <th colspan="7" scope="col" style="text-align: center;">Operand B</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <th scope="row"> </th>
   <td> </td>
   <td style="text-align: center;">Undefined</td>
   <td style="text-align: center;">Null</td>
   <td style="text-align: center;">Number</td>
   <td style="text-align: center;">String</td>
   <td style="text-align: center;">Boolean</td>
   <td style="text-align: center;">Object</td>
  </tr>
  <tr>
   <th colspan="1" rowspan="6" scope="row">Operand A</th>
   <td>Undefined</td>
   <td style="text-align: center;"><code>true</code></td>
   <td style="text-align: center;"><code>true</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>IsFalsy(B)</code></td>
  </tr>
  <tr>
   <td>Null</td>
   <td style="text-align: center;"><code>true</code></td>
   <td style="text-align: center;"><code>true</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>IsFalsy(B)</code></td>
  </tr>
  <tr>
   <td>Number</td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>A === B</code></td>
   <td style="text-align: center;"><code>A === ToNumber(B)</code></td>
   <td style="text-align: center;"><code>ToNumber(B) === A</code></td>
   <td style="text-align: center;"><code>ToPrimitive(B) == A</code></td>
  </tr>
  <tr>
   <td>String</td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>B === ToNumber(A)</code></td>
   <td style="text-align: center;"><code>A === B</code></td>
   <td style="text-align: center;"><code>ToNumber(A) === ToNumber(B)</code></td>
   <td style="text-align: center;"><code>ToPrimitive(B) == A</code></td>
  </tr>
  <tr>
   <td>Boolean</td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;"><code>ToNumber(A) === B</code></td>
   <td style="text-align: center;"><code>ToNumber(A) === ToNumber(B)</code></td>
   <td style="text-align: center;"><code>A === B</code></td>
   <td style="text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td>Object</td>
   <td style="text-align: center;"><code>IsFalsy(A)</code></td>
   <td style="text-align: center;"><code>IsFalsy(A)</code></td>
   <td style="text-align: center;"><code>ToPrimitive(A) == B</code></td>
   <td style="text-align: center;"><code>ToPrimitive(A) == B</code></td>
   <td style="text-align: center;"><code>false</code></td>
   <td style="text-align: center;">
    <p><code>A === B</code></p>
   </td>
  </tr>
 </tbody>
</table>

<p>In der oberen Tabelle versucht <code>ToNumber(A)</code> sein Argument vor dem Vergleich in eine Zahl zu konvertieren. Das Verhalten ist äquivalent zu <code>+A</code> (der unäre + Operator).  <code>ToPrimitive(A)</code> versucht sein Argument, das ein Objekt ist, in einen primitiven Wert zu konvertieren. Dazu wird eine unterschiedliche Sequenz von <code>A.toString</code> und <code>A.valueOf</code> Methoden von <code>A</code> aufzurufen.</p>

<p>Traditionell und laut ECMAScript sind alle Objekte lose ungleich zu <code>undefined</code> und <code>null</code>. Aber die meisten Webbbrowser erlauben einer sehr kleinen Menge von Objekten (speziell das <code>document.all</code> Objekt für jede Seite), dass sie sich in bestimmten Kontexten so verhalten, als ob sie den Wert <code>undefined</code> <em>emulieren</em>.  Lose Gleichheit ist ein derartiger Kontext. Daher ergibt die Methode <code>IsFalsy(A)</code> genau dann <code>true</code>, wenn A ein Objekt ist, das <code>undefined</code> <em>emuliert</em>. In allen anderen Fällen ist ein Objekt nie lose gleich zu <code>undefined</code> oder <code>null</code>.</p>

<pre class="brush: js">var num = 0;
var obj = new String("0");
var str = "0";
var b = false;

console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true

console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);
</pre>

<p>Manche Entwickler haben die Ansicht, dass die Verwendung der losen Gleichheit fast nie eine gute Idee ist. Das Resultat des<span style="line-height: 1.5;"> Vergleichs mit strikter Gleichheit ist einfacher vorherzusagen und die Auswertung ist schneller, da keine Konvertierung der Werte stattfindet</span><span style="line-height: 1.5;">.</span></p>

<h2 id="Same-value_Gleichheit">Same-value Gleichheit</h2>

<p>Same-value Gleichheit adressiert den dritten Fall: Bestimmung, ob zwei Werte in allen Kontexten <em>funktional identisch</em> sind. Dieser Anwendungsfall demonstriert eine Instanz des <a href="http://de.wikipedia.org/wiki/Liskovsches_Substitutionsprinzip">Liskovschen Substitutionsprinzip</a>. Eine Instanz tritt auf, wenn versucht wird ein nicht veränderbares Property zu verändern:</p>

<pre class="brush: js">// Add an immutable NEGATIVE_ZERO property to the Number constructor.
Object.defineProperty(Number, "NEGATIVE_ZERO",
                      { value: -0, writable: false, configurable: false, enumerable: false });

function attemptMutation(v)
{
  Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
</pre>

<p><code>Object.defineProperty</code> wird eine Exception werfen, wenn ein Versuch zum Verändern eines unveränderbares Property es verändern würde. Es passiert nichts, solange keine Veränderung stattfinden soll.  Wenn <code>v</code> <code>-0</code> ist, wurde keine Veränderung angefragt und somit wird keine Exception geworfen. Wenn <code>v</code> aber <code>+0</code> ist, hätte <code>Number.NEGATIVE_ZERO</code> nicht länger seinen unveränderbaren Wert. Wenn ein unveränderbares Property neudefiniert wird, wird der neu spezifizierte Wert intern mittels der Same-value Gleichheit mit dem aktuellen Wert verglichen.</p>

<p>Die Same-value Gleichheit wird von der <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> Methode angeboten.</p>

<h2 id="Abstrakte_Gleichheit_strikte_Gleichheit_und_same-value_Gleichheit_in_der_Spezifikation">Abstrakte Gleichheit, strikte Gleichheit und same-value Gleichheit in der Spezifikation</h2>

<p>In ECMAScript 5 wird der Vergleich mit <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>==</code></a> in <a href="http://ecma-international.org/ecma-262/5.1/#sec-11.9.3" title="http://ecma-international.org/ecma-262/5.1/#sec-11.9.3">Section 11.9.3, The Abstract Equality Algorithm</a> beschrieben. Der <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a> Vergleich ist in <a href="http://ecma-international.org/ecma-262/5.1/#sec-11.9.6" title="http://ecma-international.org/ecma-262/5.1/#sec-11.9.6">11.9.6, The Strict Equality Algorithm</a> zu finden. (Diese beiden Abschnitte sind kurz und verständlich. Hinweis: zuerst den Abschnitt Strict Equality Algorithm lesen) ECMAScript 5 beschreibt auch die same-value Gleichheit in <a href="http://ecma-international.org/ecma-262/5.1/#sec-9.12">Section 9.12, The SameValue Algorithm</a> für die interne Verwendung in der JavaScript Engine. Dieser Abschnitt ist hauptsächlich derselbe wie Strict Equality Algorithm mit der Ausnahme, dass sich 11.9.6.4 und 9.12.4 in der Behandlung von Zahlen (<a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number"><code>Number</code></a>) unterscheiden. ECMAScript 2015 schlägt vor, dass dieser Algorithmus über <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> angeboten wird.</p>

<p>Wir können erkennen, dass mit double und triple equals, mit der Ausnahme der vorhergehenden Typkonvertierung in 11.9.6.1, der Strict Equality Algorithm eine Teilmenge des Abstract Equality Algorithm ist, weil 11.9.6.2–7 dem Abschnitt 11.9.3.1.a–f entspricht.</p>

<h2 id="A_model_for_understanding_equality_comparisons">A model for understanding equality comparisons?</h2>

<p>Prior to ES2015, you might have said of double equals and triple equals that one is an "enhanced" version of the other. For example, someone might say that double equals is an extended version of triple equals, because the former does everything that the latter does, but with type conversion on its operands. E.g., <code>6 == "6"</code>. (Alternatively, someone might say that double equals is the baseline, and triple equals is an enhanced version, because it requires the two operands to be the same type, so it adds an extra constraint. Which one is the better model for understanding depends on how you choose to view things.)</p>

<p>However, this way of thinking about the built-in sameness operators is not a model that can be stretched to allow a place for ES2015's <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> on this "spectrum". <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> isn't simply "looser" than double equals or "stricter" than triple equals, nor does it fit somewhere in between (i.e., being both stricter than double equals, but looser than triple equals). We can see from the sameness comparisons table below that this is due to the way that <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> handles <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>. Notice that if <code>Object.is(NaN, NaN)</code> evaluated to <code>false</code>, we <em>could</em> say that it fits on the loose/strict spectrum as an even stricter form of triple equals, one that distinguishes between <code>-0</code> and <code>+0</code>. The <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> handling means this is untrue, however. Unfortunately, <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> simply has to be thought of in terms of its specific characteristics, rather than its looseness or strictness with regard to the equality operators.</p>

<table class="standard-table">
 <caption>Sameness Comparisons</caption>
 <thead>
  <tr>
   <th scope="col" style="text-align: center;">x</th>
   <th scope="col" style="text-align: center;">y</th>
   <th scope="col" style="width: 10em; text-align: center;"><code>==</code></th>
   <th scope="col" style="width: 10em; text-align: center;"><code>===</code></th>
   <th scope="col" style="width: 10em; text-align: center;"><code>Object.is</code></th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><code>undefined</code></td>
   <td><code>undefined</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>null</code></td>
   <td><code>null</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>true</code></td>
   <td><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>false</code></td>
   <td><code>false</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>"foo"</code></td>
   <td><code>"foo"</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>{ foo: "bar" }</code></td>
   <td><code>x</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>0</code></td>
   <td><code>0</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
  <tr>
   <td><code>+0</code></td>
   <td><code>-0</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>0</code></td>
   <td><code>false</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>""</code></td>
   <td><code>false</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>""</code></td>
   <td><code>0</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>"0"</code></td>
   <td><code>0</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>"17"</code></td>
   <td><code>17</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>[1,2]</code></td>
   <td><code>"1,2"</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>new String("foo")</code></td>
   <td><code>"foo"</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>null</code></td>
   <td><code>undefined</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>null</code></td>
   <td><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>undefined</code></td>
   <td><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>{ foo: "bar" }</code></td>
   <td><code>{ foo: "bar" }</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>new String("foo")</code></td>
   <td><code>new String("foo")</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>0</code></td>
   <td><code>null</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>0</code></td>
   <td><code>NaN</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>"foo"</code></td>
   <td><code>NaN</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
  </tr>
  <tr>
   <td><code>NaN</code></td>
   <td><code>NaN</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td>
   <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
  </tr>
 </tbody>
</table>

<h2 id="When_to_use_Object.is_versus_triple_equals">When to use <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> versus triple equals</h2>

<p>Aside from the way it treats <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>, generally, the only time <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a>'s special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors when it is desirable for your work to mirror some of the characteristics of <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty</code></a>. If your use case does not require this, it is suggested to avoid <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> and use <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a> instead. Even if your requirements involve having comparisons between two <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> values evaluate to <code>true</code>, generally it is easier to special-case the <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> checks (using the <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN"><code>isNaN</code></a> method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.</p>

<p>Here's an in-exhaustive list of built-in methods and operators that might cause a distinction between <code>-0</code> and <code>+0</code> to manifest itself in your code:</p>

<dl>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#-_.28Unary_Negation.29" title="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators"><code>- (unary negation)</code></a></dt>
</dl>

<dl>
 <dd>
 <p>It's obvious that negating <code>0</code> produces <code>-0</code>. But the abstraction of an expression can cause <code>-0</code> to creep in when you don't realize it. For example, consider:</p>

 <pre class="brush:js">let stoppingForce = obj.mass * -obj.velocity</pre>

 <p>If <code>obj.velocity</code> is <code>0</code> (or computes to <code>0</code>), a <code>-0</code> is introduced at that place and propogates out into <code>stoppingForce</code>.</p>
 </dd>
</dl>

<dl>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2"><code>Math.atan2</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil"><code>Math.ceil</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow"><code>Math.pow</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round"><code>Math.round</code></a></dt>
</dl>

<dl>
 <dd>It's possible for a <code>-0</code> to be introduced into an expression as a return value of these methods in some cases, even when no <code>-0</code> exists as one of the parameters. E.g., using <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow"><code>Math.pow</code></a> to raise <code>-<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity">Infinity</a></code> to the power of any negative, odd exponent evaluates to <code>-0</code>. Refer to the documentation for the individual methods.</dd>
</dl>

<dl>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor"><code>Math.floor</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max"><code>Math.max</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min"><code>Math.min</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin"><code>Math.sin</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt"><code>Math.sqrt</code></a></dt>
 <dt><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan"><code>Math.tan</code></a></dt>
</dl>

<dl>
 <dd>It's possible to get a <code>-0</code> return value out of these methods in some cases where a <code>-0</code> exists as one of the parameters. E.g., <code>Math.min(-0, +0)</code> evalutes to <code>-0</code>. Refer to the documentation for the individual methods.</dd>
</dl>

<dl>
 <dt><code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">~</a></code></dt>
 <dt><code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">&lt;&lt;</a></code></dt>
 <dt><code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">&gt;&gt;</a></code></dt>
 <dd>Each of these operators uses the ToInt32 algorithm internally. Since there is only one representation for 0 in the internal 32-bit integer type, <code>-0</code> will not survive a round trip after an inverse operation. E.g., both <code>Object.is(~~(-0), -0)</code> and <code>Object.is(-0 &lt;&lt; 2 &gt;&gt; 2, -0)</code> evaluate to <code>false</code>.</dd>
</dl>

<p>Relying on <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> when the signedness of zeros is not taken into account can be hazardous. Of course, when the intent is to distinguish between <code>-0</code> and <code>+0</code>, it does exactly what's desired.</p>

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

<ul>
 <li><a href="http://dorey.github.io/JavaScript-Equality-Table/">JS Comparison Table</a></li>
</ul>