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
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
|
---
title: Перевірка на рівність та однаковість
slug: Web/JavaScript/Equality_comparisons_and_sameness
tags:
- JavaScript
- NaN
- SameValue
- SameValueZero
- Однаковість
- Рівність
- Тотожність
- порівняння
translation_of: Web/JavaScript/Equality_comparisons_and_sameness
original_slug: Web/JavaScript/Перевірка_на_рівність_та_однаковість
---
<div>{{jsSidebar("Intermediate")}}</div>
<p>У ES2015 існує чотири алгоритми рівності:</p>
<ul>
<li>Абстрактна рівність (<code>==</code>);</li>
<li>Строга рівність (<code>===</code>): вживається у методах <code>Array.prototype.indexOf</code>, <code>Array.prototype.lastIndexOf</code> та у блоках <code>case</code>;</li>
<li>SameValueZero (однакове значення або нуль): вживається конструкторами {{jsxref("Global_Objects/TypedArray", "типізованих масивів")}} та {{jsxref("Global_Objects/ArrayBuffer", "ArrayBuffer")}}, так само, як і операціями з {{jsxref("Global_Objects/Map", "Map")}} та {{jsxref("Global_Objects/Set", "Set")}}, а також методами <code>String.prototype.includes</code> та <code>Array.prototype.includes</code>, починаючи з ES2016;</li>
<li>SameValue (однакове значення): вживається у решті випадків.</li>
</ul>
<p>JavaScript надає три різні операції порівняння значень:</p>
<ul>
<li><a href="/uk/docs/Web/JavaScript/Reference/Operators/Оператори_порівняння#Ідентичність_строга_рівність_()">===</a> - Строга рівність ("ідентичність", "потрійне дорівнює")</li>
<li><a href="/uk/docs/Web/JavaScript/Reference/Operators/Оператори_порівняння#Рівність_()">==</a> - Абстрактна рівність ("нестрога рівність", "подвійне дорівнює")</li>
<li>метод {{jsxref("Object.is")}} реалізує SameValue (нове у ES2015).</li>
</ul>
<p>Вибір оператора залежитиме від того, який різновид порівняння вам потрібен. Коротко:</p>
<ul>
<li>подвійне дорівнює (<code>==</code>) виконає приведення типів при порівнянні двох величин, і оброблятиме <code>NaN</code>, <code>-0</code> та <code>+0</code> особливим чином, у відповідності з IEEE 754 (тому <code>NaN != NaN</code>, а <code>-0 == +0</code>);</li>
<li>потрійне дорівнює (<code>===</code>) виконує таке саме порівняння, як і подвійне дорівнює (і так само поводиться з <code>NaN</code>, <code>-0</code> та <code>+0</code>), але без приведення типів; якщо типи величин відрізняються, повертається <code>false</code>.</li>
<li><code>Object.is</code> не виконує приведення типів та не обробляє <code>NaN</code>, <code>-0</code> та <code>+0</code> особливим чином (має таку саму поведінку, як і <code>===</code>, за винятком цих спеціальних числових значень).</li>
</ul>
<p>Зауважте, що усі відмінності операторів стосуються їхнього поводження з простими величинами; жоден з них не порівнює, чи є параметри концептуально однаковими за структурою. Для будь-яких не примітивних об'єктів <code>x</code> та <code>y</code>, що мають однакову структуру, але є двома окремими об'єктами, всі вищенаведені форми порівняння вертатимуть <code>false</code>.</p>
<h2 id="Строга_рівність_за_допомогою">Строга рівність за допомогою <code>===</code></h2>
<p>Строга рівність перевіряє рівність двох значень. До жодного з них не застосовується неявне приведення перед порівнянням. Якщо значення мають різні типи, вони вважаються нерівними. Якщо значення мають однаковий тип, не є числами, і мають однакові значення, вони вважаються рівними. Нарешті, якщо обидва значення є числами, вони вважаються рівними, якщо обидва не дорівнюють <code>NaN</code> та мають однакові значення, або якщо одне дорівнює <code>+0</code>, а інше <code>-0</code>.</p>
<pre class="brush: js">var num = 0;
var obj = new String('0');
var str = '0';
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>Строга рівність майже завжди є доречною операцією порівняння. Для усіх значень, крім чисел, вона використовує очевидну семантику: значення дорівнює лише самому собі. Для чисел вона використовує трохи відмінну семантику, щоб згладити два граничні випадки. Перший полягає в тому, що нуль з рухомою комою є або додатним, або від'ємним. Це корисно для представлення деяких математичних рішень, але, оскільки у більшості ситуацій різниця між <code>+0</code> та <code>-0</code> не має значення, строга рівність вважає їх одним значенням. Другий випадок полягає в тому, що рухома кома містить концепцію не числа, <code>NaN</code> (not a number), для вирішення деяких нечітко визначених математичних проблем: наприклад, від'ємна нескінченність, додана до позитивної нескінченності. Строга рівність вважає значення <code>NaN</code> нерівним будь-якій іншій величині, в тому числі самому собі. (Єдиний випадок, у якому <code>(x !== x)</code> дорівнює <code>true</code>, це коли <code>x</code> дорівнює <code>NaN</code>.)</p>
<h2 id="Нестрога_рівність_за_допомогою">Нестрога рівність за допомогою ==</h2>
<p>Нестрога рівність порівнює два значення <em>після</em> приведення обох значень до спільного типу. Після приведення (один чи обидва значення можуть зазнати перетворення), фінальне порівняння виконується так само, як його виконує оператор <code>===</code>. Нестрога рівність є <em>симетричною</em>: вираз <code>A == B</code> за семантикою завжди ідентичний <code>B == A</code> для будь-яких значень <code>A</code> та <code>B</code> (за винятком порядку, в якому виконуються перетворення).</p>
<p>Порівняльна операція виконується наступним чином для операндів різних типів:</p>
<table class="standard-table">
<thead>
<tr>
<th scope="row"></th>
<th colspan="7" scope="col" style="text-align: center;">Операнд 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">Операнд 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>false</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>false</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>A === ToNumber(B)</code></td>
<td style="text-align: center;"><code>A == ToPrimitive(B)</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>ToNumber(A) === B</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>A == ToPrimitive(B)</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>ToNumber(A) == ToPrimitive(B)</code></td>
</tr>
<tr>
<td>Object</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>ToPrimitive(A) == B</code></td>
<td style="text-align: center;"><code>ToPrimitive(A) == B</code></td>
<td style="text-align: center;"><code>ToPrimitive(A) == ToNumber(B)</code></td>
<td style="text-align: center;"><code>A === B</code></td>
</tr>
</tbody>
</table>
<p>У наведеній вище таблиці <code>ToNumber(A)</code> пробує перетворити свій аргумент на число перед порівнянням. Його поведінка еквівалентна операції <code>+A</code> (унарний оператор +). <code>ToPrimitive(A)</code> пробує перетворити свій аргумент-об'єкт на просту величину, викликаючи в різній послідовності методи <code>A.toString</code> та <code>A.valueOf</code> на операнді <code>A</code>.</p>
<p>Традиційно, та згідно з ECMAScript, усі об'єкти нестрого нерівні <code>undefined</code> та <code>null</code>. Але більшість переглядачів дозволяють дуже вузькому класу об'єктів (зокрема, об'єкту <code>document.all</code> на будь-якій сторінці) у певному контексті поводитись, як наче вони <em>емулюють</em> значення <code>undefined</code>. Нестрога рівність у такому контексті: <code>null == A</code> та <code>undefined == A</code> оцінить як true тільки за умови, що A є об'єктом, який <em>емулює</em> <code>undefined</code>. У всіх інших випадках об'єкт ніколи не є нестрого рівним <code>undefined</code> або <code>null</code>.</p>
<pre class="brush: js">var num = 0;
var obj = new String('0');
var str = '0';
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
// обидва дорівнюють false, крім виняткових випадків
console.log(obj == null);
console.log(obj == undefined);
</pre>
<p>Деякі розробники вважають, що краще ніколи не використовувати нестрогу рівність. Результат порівняння за допомогою строгої рівності легше передбачити, а, оскільки жодного приведення типів не виконується, обчислення може відбуватись швидше.</p>
<h2 id="Порівняння_за_алгоритмом_same-value">Порівняння за алгоритмом same-value</h2>
<p>Порівняння same-value (однакове значення) спрямоване на останній випадок використання: визначення того, чи є два значення <em>функціонально ідентичними</em> в усіх контекстах. (Цей випадок використання демонструє приклад <a href="https://uk.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86%D0%B8%D0%BF_%D0%BF%D1%96%D0%B4%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B8_%D0%9B%D1%96%D1%81%D0%BA%D0%BE%D0%B2" title="http://en.wikipedia.org/wiki/Liskov_substitution_principle">принципу підстановки Лісков</a>.) Один приклад виникає, коли робиться спроба змінити незмінну властивість:</p>
<pre class="brush: js">// Додати незмінну властивість NEGATIVE_ZERO у конструктор Number.
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> викине виняток, коли спроба змінити незмінну властивість дійсно змінить її, але нічого не зробить, якщо не робиться запитів на реальну зміну. Якщо <code>v</code> дорівнює <code>-0</code>, запитів на зміну не виконувалось, жодна помилка не буде викинута. Внутрішньо, коли перевизначається незмінна властивість, нове значення порівнюється з наявним значенням за допомогою алгоритму same-value.</p>
<p>Алгоритм same-value надається методом {{jsxref("Object.is")}}.</p>
<h2 id="Порівняння_за_алгоритмом_same-value-zero">Порівняння за алгоритмом same-value-zero</h2>
<p>Схожий на алгоритм same-value, але вважає +0 та -0 рівними.</p>
<h2 id="Абстрактна_рівність_строга_рівність_та_однакове_значення_у_специфікації">Абстрактна рівність, строга рівність та однакове значення у специфікації</h2>
<p>У ES5 порівняння, що виконується за допомогою <a href="/uk/docs/Web/JavaScript/Reference/Operators/Оператори_порівняння#Рівність_()" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>==</code></a>, описане у <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">Розділі 11.9.3, Алгоритм абстрактної рівності</a>. Порівняння <a href="/uk/docs/Web/JavaScript/Reference/Operators/Оператори_порівняння#Ідентичність_строга_рівність_()" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a> у <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, Алгоритм строгої рівності</a>. (Сходіть почитайте. Вони короткі та легкі для читання. Підказка: читайте спочатку алгоритм строгої рівності.) ES5 також описує, у <a href="http://ecma-international.org/ecma-262/5.1/#sec-9.12" title="http://ecma-international.org/ecma-262/5.1/#sec-9.12">Розділі 9.12, Алгоритм SameValue</a>, для внутрішнього використання рушієм JS. Він значною мірою такий самий, як алгоритм строгої рівності, за винятком того, як 11.9.6.4 та 9.12.4 відрізняються у поводженні з {{jsxref("Number","числами")}}. ES2015 просто відкриває цей алгоритм через {{jsxref("Object.is")}}.</p>
<p>Щодо подвійного та потрійного дорівнює, можна побачити, що, за винятком попередньої перевірки типу у 11.9.6.1, алгоритм строгої рівності є підмножиною алгоритму абстрактної рівності, бо 11.9.6.2–7 відповідають 11.9.3.1.a–f.</p>
<h2 id="Модель_для_розуміння_порівняльних_алгоритмів">Модель для розуміння порівняльних алгоритмів?</h2>
<p>До ES2015 ви, можливо, сказали б щодо подвійного та потрійного дорівнює, що один є "посиленою" версією іншого. Наприклад, хтось може сказати, що подвійне дорівнює є посиленою версією потрійного дорвінює, тому що перше робить усе, що робить друге, але з приведенням типів у операндах. Наприклад, <code>6 == "6"</code>. (Альтернативно, хтось може сказати, що подвійне дорівнює є основою, а потрійне дорівнює є посиленою версією, тому що воно вимагає, щоб два операнди були однакового типу, і таким чином, вводить додаткове обмеження. Яка модель краща для розуміння, залежить від того, яким чином ви розглядаєте питання.)</p>
<p>Однак, така модель вбудованих операторів однаковості не може бути поширена на ES2015 з включенням у свій "діапазон" методу {{jsxref("Object.is")}}. Метод {{jsxref("Object.is")}} не просто "абстрактніший", ніж подвійне, або "суворіший", ніж потрійне дорівнює, він також не вписується десь посередині (тобто, будучи одночасно суворішим за подвійне дорівнює, але менш строгим за потрійне дорівнює). Як можна побачити з наведеної нижче порівняльної таблиці, все через поводження {{jsxref("Object.is")}} з {{jsxref("NaN")}}. Зверніть увагу, що, якби значення <code>Object.is(NaN, NaN)</code> дорівнювало <code>false</code>, ми <em>могли б</em> сказати, що метод вписується у абстрактно-суворий діапазон як ще суворіший за потрійне дорівнює, такий, що розрізняє <code>-0</code> та <code>+0</code>. Однак, його поводження з {{jsxref("NaN")}} означає, що це не так. На жаль, {{jsxref("Object.is")}} просто має сприйматись з точки зору його особливих характеристик, а не його абстрактності чи суворості у порівнянні з операторами рівності.</p>
<table class="standard-table" style="height: 944px; width: 892px;">
<caption>Порівняльні алгоритми</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>
<th scope="col" style="width: 10em; text-align: center;"><code>SameValueZero</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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td>
</tr>
</tbody>
</table>
<h2 id="Коли_використовувати_jsxrefObject.is_та_потрійне_дорівнює">Коли використовувати {{jsxref("Object.is")}} та потрійне дорівнює</h2>
<p>Загалом, єдиний випадок, коли особлива поведінка {{jsxref("Object.is")}} щодо нулів може становити інтерес, це впровадження певних схем метапрограмування, особливо тих, що стосуються дескрипторів властивостей, коли бажано, щоб ваша робота відображала певні характеристики {{jsxref("Object.defineProperty")}}. Якщо ваш випадок цього не вимагає, пропонується уникати {{jsxref("Object.is")}} та використовувати натомість <a href="/uk/docs/Web/JavaScript/Reference/Operators/Оператори_порівняння#Ідентичність_строга_рівність_()" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a>. Навіть якщо у вашому випадку вимагається, щоб порівняння двох {{jsxref("NaN")}} повертало <code>true</code>, загалом, легше перевіряти {{jsxref("NaN")}} окремо (за допомогою методу {{jsxref("isNaN")}}, доступного у попередніх версіях ECMAScript), ніж розбиратися, як навколишні обчислення можуть вплинути на знаки нулів, які зустрінуться вам у порівняннях.</p>
<p>Ось невичерпний список вбудованих методів та операцій, що можуть спричинити відмінності між <code>-0</code> та <code>+0</code>, які можуть проявити себе у коді:</p>
<dl>
<dt><a href="/uk/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation"><code>- (унарний мінус)</code></a></dt>
</dl>
<dl>
<dd>
<pre class="brush:js">let stoppingForce = obj.mass * -obj.velocity;</pre>
<p>Якщо <code>obj.velocity</code> дорівнює <code>0</code> (або обчислюється як <code>0</code>), в цьому місці отримуємо <code>-0</code>, який переходить далі у <code>stoppingForce</code>.</p>
</dd>
</dl>
<dl>
<dt>{{jsxref("Math.atan2")}}</dt>
<dt>{{jsxref("Math.ceil")}}</dt>
<dt>{{jsxref("Math.pow")}}</dt>
<dt>{{jsxref("Math.заокругелння","Math.round")}}</dt>
</dl>
<dl>
<dd>У деяких випадках <code>-0</code> може потрапити у вираз як результат одного з цих методів, навіть коли жоден параметр не дорівнює <code>-0</code>. Наприклад, при використанні {{jsxref("Math.pow")}} для піднесення {{jsxref("Infinity", "-Infinity")}} до будь-якого від'ємного непарного степеня, отримуємо <code>-0</code>. Звертайтесь до документації щодо окремих методів.</dd>
</dl>
<dl>
<dt>{{jsxref("Math.floor")}}</dt>
<dt>{{jsxref("Math.max")}}</dt>
<dt>{{jsxref("Math.min")}}</dt>
<dt>{{jsxref("Math.sin")}}</dt>
<dt>{{jsxref("Math.sqrt")}}</dt>
<dt>{{jsxref("Math.tan")}}</dt>
</dl>
<dl>
<dd>Можливо отримати <code>-0</code> як результат виконання даних методів у певних випадках, коли <code>-0</code> присутній як один з параметрів. Наприклад, <code>Math.min(-0, +0)</code> повертає <code>-0</code>. Звертайтесь до документації щодо окремих методів.</dd>
</dl>
<dl>
<dt><code><a href="/uk/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Побітове_НЕ" title="Побітове НЕ">~</a></code></dt>
<dt><code><a href="/uk/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#<<_Лівий_зсув" title="Лівий зсув"><<</a></code></dt>
<dt><code><a href="/uk/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#>>_Правий_зсув_з_розширенням_знаку" title="Правий зсув з розширенням знаку">>></a></code></dt>
<dd>Кожний з цих операторів внутрішньо використовує алгоритм ToInt32. Оскільки існує лише одне представлення 0 у внутрішньому 32-бітному цілочисельному типі, <code>-0</code> не збережеться після подвійної операції інверсії. Наприклад, і <code>Object.is(~~(-0), -0)</code>, і <code>Object.is(-0 << 2 >> 2, -0)</code> повернуть <code>false</code>.</dd>
</dl>
<p>Покладатися на метод {{jsxref("Object.is")}}, не беручи до уваги знаки нулів, може бути небезпечно. Звісно, якщо на меті стоїть розрізнити <code>-0</code> та <code>+0</code>, він робить саме те, що потрібно.</p>
<h2 id="Попередження_jsxrefObject.is_та_NaN">Попередження: {{jsxref("Object.is")}} та NaN</h2>
<p>Специфікація {{jsxref("Object.is")}} вважає усі екземпляри {{jsxref("NaN")}} тим самим об'єктом, але, оскільки нам доступні <a href="/uk/docs/Web/JavaScript/Typed_arrays">типізовані масиви</a>, ми можемо мати окремі екземпляри, які не поводитимуться ідентично в усіх контекстах. Приклад:</p>
<pre class="brush: js">var f2b = x => new Uint8Array(new Float64Array([x]).buffer);
var b2f = x => new Float64Array(x.buffer)[0];
var n = f2b(NaN);
n[0] = 1;
var nan2 = b2f(n);
nan2
> NaN
Object.is(nan2, NaN)
> true
f2b(NaN)
> Uint8Array(8) [0, 0, 0, 0, 0, 0, 248,127)
f2b(nan2)
> Uint8Array(8) [1, 0, 0, 0, 0, 0, 248,127)</pre>
<h2 id="Див._також">Див. також</h2>
<ul>
<li><a href="http://dorey.github.io/JavaScript-Equality-Table/">JS Comparison Table</a></li>
</ul>
|