-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathcomparison-operations.html
More file actions
425 lines (348 loc) · 140 KB
/
comparison-operations.html
File metadata and controls
425 lines (348 loc) · 140 KB
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
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>JavsScript - Comparison Operations</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="Abstract equality / inequality and type conversion, NaN Property of the Global Object, Short-circuiting in boolean operators, Abstract Equality (==), Null and Undefined, Logic Operators with Booleans, Logic Operators with Non-boolean values (boolean coercion), Empty Array, Automatic Type Conversions, Equality comparison operations, Relational operators (<, <=, >, >=), Inequality, Grouping multiple logic statements, List of Comparison Operators, Bit fields to optimise comparison of multi state data">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="JavsScript - Comparison Operations">
<meta property="og:description" content="Abstract equality / inequality and type conversion, NaN Property of the Global Object, Short-circuiting in boolean operators, Abstract Equality (==), Null and Undefined, Logic Operators with Booleans, Logic Operators with Non-boolean values (boolean coercion), Empty Array, Automatic Type Conversions, Equality comparison operations, Relational operators (<, <=, >, >=), Inequality, Grouping multiple logic statements, List of Comparison Operators, Bit fields to optimise comparison of multi state data">
<meta property="og:type" content="article">
<meta property="og:url" content="/javascript/comparison-operations.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="JavsScript - Comparison Operations">
<meta name="twitter:description" content="Abstract equality / inequality and type conversion, NaN Property of the Global Object, Short-circuiting in boolean operators, Abstract Equality (==), Null and Undefined, Logic Operators with Booleans, Logic Operators with Non-boolean values (boolean coercion), Empty Array, Automatic Type Conversions, Equality comparison operations, Relational operators (<, <=, >, >=), Inequality, Grouping multiple logic statements, List of Comparison Operators, Bit fields to optimise comparison of multi state data">
<meta name="twitter:url" content="/javascript/comparison-operations.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/1717.17528fff.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>JavaScript</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/javascript/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/javascript/getting-started-with-javascript.html" class="sidebar-link">Getting started with JavaScript</a></li><li><a href="/javascript/javascript-variables.html" class="sidebar-link">JavaScript Variables</a></li><li><a href="/javascript/built-in-constants.html" class="sidebar-link">Built-in Constants</a></li><li><a href="/javascript/comments.html" class="sidebar-link">Comments</a></li><li><a href="/javascript/console.html" class="sidebar-link">Console</a></li><li><a href="/javascript/datatypes-in-javascript.html" class="sidebar-link">Datatypes in Javascript</a></li><li><a href="/javascript/strings.html" class="sidebar-link">Strings</a></li><li><a href="/javascript/date.html" class="sidebar-link">Date</a></li><li><a href="/javascript/date-comparison.html" class="sidebar-link">Date Comparison</a></li><li><a href="/javascript/comparison-operations.html" aria-current="page" class="active sidebar-link">Comparison Operations</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#abstract-equality-inequality-and-type-conversion" class="sidebar-link">Abstract equality / inequality and type conversion</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#nan-property-of-the-global-object" class="sidebar-link">NaN Property of the Global Object</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#short-circuiting-in-boolean-operators" class="sidebar-link">Short-circuiting in boolean operators</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#abstract-equality" class="sidebar-link">Abstract Equality (==)</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#null-and-undefined" class="sidebar-link">Null and Undefined</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#logic-operators-with-booleans" class="sidebar-link">Logic Operators with Booleans</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#logic-operators-with-non-boolean-values-boolean-coercion" class="sidebar-link">Logic Operators with Non-boolean values (boolean coercion)</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#empty-array" class="sidebar-link">Empty Array</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#automatic-type-conversions" class="sidebar-link">Automatic Type Conversions</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#equality-comparison-operations" class="sidebar-link">Equality comparison operations</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#relational-operators" class="sidebar-link">Relational operators (=)</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#inequality" class="sidebar-link">Inequality</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#grouping-multiple-logic-statements" class="sidebar-link">Grouping multiple logic statements</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#list-of-comparison-operators" class="sidebar-link">List of Comparison Operators</a></li><li class="sidebar-sub-header"><a href="/javascript/comparison-operations.html#bit-fields-to-optimise-comparison-of-multi-state-data" class="sidebar-link">Bit fields to optimise comparison of multi state data</a></li></ul></li><li><a href="/javascript/conditions.html" class="sidebar-link">Conditions</a></li><li><a href="/javascript/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/javascript/objects.html" class="sidebar-link">Objects</a></li><li><a href="/javascript/arithmetic-math.html" class="sidebar-link">Arithmetic (Math)</a></li><li><a href="/javascript/bitwise-operators.html" class="sidebar-link">Bitwise operators</a></li><li><a href="/javascript/constructor-functions.html" class="sidebar-link">Constructor functions</a></li><li><a href="/javascript/declarations-and-assignments.html" class="sidebar-link">Declarations and Assignments</a></li><li><a href="/javascript/loops.html" class="sidebar-link">Loops</a></li><li><a href="/javascript/functions.html" class="sidebar-link">Functions</a></li><li><a href="/javascript/functional-javascript.html" class="sidebar-link">Functional JavaScript</a></li><li><a href="/javascript/prototypes-objects.html" class="sidebar-link">Prototypes, objects</a></li><li><a href="/javascript/classes.html" class="sidebar-link">Classes</a></li><li><a href="/javascript/namespacing.html" class="sidebar-link">Namespacing</a></li><li><a href="/javascript/context-this.html" class="sidebar-link">Context (this)</a></li><li><a href="/javascript/setters-and-getters.html" class="sidebar-link">Setters and Getters</a></li><li><a href="/javascript/events.html" class="sidebar-link">Events</a></li><li><a href="/javascript/inheritance.html" class="sidebar-link">Inheritance</a></li><li><a href="/javascript/method-chaining.html" class="sidebar-link">Method Chaining</a></li><li><a href="/javascript/callbacks.html" class="sidebar-link">Callbacks</a></li><li><a href="/javascript/intervals-and-timeouts.html" class="sidebar-link">Intervals and Timeouts</a></li><li><a href="/javascript/regular-expressions.html" class="sidebar-link">Regular expressions</a></li><li><a href="/javascript/cookies.html" class="sidebar-link">Cookies</a></li><li><a href="/javascript/web-storage.html" class="sidebar-link">Web Storage</a></li><li><a href="/javascript/data-attributes.html" class="sidebar-link">Data attributes</a></li><li><a href="/javascript/json.html" class="sidebar-link">JSON</a></li><li><a href="/javascript/ajax.html" class="sidebar-link">AJAX</a></li><li><a href="/javascript/enumerations.html" class="sidebar-link">Enumerations</a></li><li><a href="/javascript/map.html" class="sidebar-link">Map</a></li><li><a href="/javascript/timestamps.html" class="sidebar-link">Timestamps</a></li><li><a href="/javascript/unary-operators.html" class="sidebar-link">Unary Operators</a></li><li><a href="/javascript/generators.html" class="sidebar-link">Generators</a></li><li><a href="/javascript/promises.html" class="sidebar-link">Promises</a></li><li><a href="/javascript/set.html" class="sidebar-link">Set</a></li><li><a href="/javascript/modals-prompts.html" class="sidebar-link">Modals - Prompts</a></li><li><a href="/javascript/execcommand-and-contenteditable.html" class="sidebar-link">execCommand and contenteditable</a></li><li><a href="/javascript/history.html" class="sidebar-link">History</a></li><li><a href="/javascript/navigator-object.html" class="sidebar-link">Navigator Object</a></li><li><a href="/javascript/bom-browser-object-model.html" class="sidebar-link">BOM (Browser Object Model)</a></li><li><a href="/javascript/the-event-loop.html" class="sidebar-link">The Event Loop</a></li><li><a href="/javascript/strict-mode.html" class="sidebar-link">Strict mode</a></li><li><a href="/javascript/custom-elements.html" class="sidebar-link">Custom Elements</a></li><li><a href="/javascript/data-manipulation.html" class="sidebar-link">Data Manipulation</a></li><li><a href="/javascript/binary-data.html" class="sidebar-link">Binary Data</a></li><li><a href="/javascript/template-literals.html" class="sidebar-link">Template Literals</a></li><li><a href="/javascript/fetch.html" class="sidebar-link">Fetch</a></li><li><a href="/javascript/scope.html" class="sidebar-link">Scope</a></li><li><a href="/javascript/modules.html" class="sidebar-link">Modules</a></li><li><a href="/javascript/screen.html" class="sidebar-link">Screen</a></li><li><a href="/javascript/variable-coercion-conversion.html" class="sidebar-link">Variable coercion/conversion</a></li><li><a href="/javascript/destructuring-assignment.html" class="sidebar-link">Destructuring assignment</a></li><li><a href="/javascript/websockets.html" class="sidebar-link">WebSockets</a></li><li><a href="/javascript/arrow-functions.html" class="sidebar-link">Arrow Functions</a></li><li><a href="/javascript/workers.html" class="sidebar-link">Workers</a></li><li><a href="/javascript/requestanimationframe.html" class="sidebar-link">requestAnimationFrame</a></li><li><a href="/javascript/creational-design-patterns.html" class="sidebar-link">Creational Design Patterns</a></li><li><a href="/javascript/detecting-browser.html" class="sidebar-link">Detecting browser</a></li><li><a href="/javascript/symbols.html" class="sidebar-link">Symbols</a></li><li><a href="/javascript/transpiling.html" class="sidebar-link">Transpiling</a></li><li><a href="/javascript/automatic-semicolon-insertion-asi.html" class="sidebar-link">Automatic Semicolon Insertion - ASI</a></li><li><a href="/javascript/localization.html" class="sidebar-link">Localization</a></li><li><a href="/javascript/geolocation.html" class="sidebar-link">Geolocation</a></li><li><a href="/javascript/indexeddb.html" class="sidebar-link">IndexedDB</a></li><li><a href="/javascript/modularization-techniques.html" class="sidebar-link">Modularization Techniques</a></li><li><a href="/javascript/proxy.html" class="sidebar-link">Proxy</a></li><li><a href="/javascript/postmessage-and-messageevent.html" class="sidebar-link">.postMessage() and MessageEvent</a></li><li><a href="/javascript/weakmap.html" class="sidebar-link">WeakMap</a></li><li><a href="/javascript/weakset.html" class="sidebar-link">WeakSet</a></li><li><a href="/javascript/escape-sequences.html" class="sidebar-link">Escape Sequences</a></li><li><a href="/javascript/behavioral-design-patterns.html" class="sidebar-link">Behavioral Design Patterns</a></li><li><a href="/javascript/server-sent-events.html" class="sidebar-link">Server-sent events</a></li><li><a href="/javascript/async-functions-async-await.html" class="sidebar-link">Async functions (async/await)</a></li><li><a href="/javascript/async-iterators.html" class="sidebar-link">Async Iterators</a></li><li><a href="/javascript/how-to-make-iterator-usable-inside-async-callback-function.html" class="sidebar-link">How to make iterator usable inside async callback function</a></li><li><a href="/javascript/tail-call-optimization.html" class="sidebar-link">Tail Call Optimization</a></li><li><a href="/javascript/bitwise-operators-real-world-examples-snippets.html" class="sidebar-link">Bitwise Operators - Real World Examples (snippets)</a></li><li><a href="/javascript/tilde.html" class="sidebar-link">Tilde ~</a></li><li><a href="/javascript/using-javascript-to-get-set-css-custom-variables.html" class="sidebar-link">Using javascript to get/set CSS custom variables</a></li><li><a href="/javascript/selection-api.html" class="sidebar-link">Selection API</a></li><li><a href="/javascript/file-api-blobs-and-filereaders.html" class="sidebar-link">File API, Blobs and FileReaders</a></li><li><a href="/javascript/notifications-api.html" class="sidebar-link">Notifications API</a></li><li><a href="/javascript/vibration-api.html" class="sidebar-link">Vibration API</a></li><li><a href="/javascript/battery-status-api.html" class="sidebar-link">Battery Status API</a></li><li><a href="/javascript/fluent-api.html" class="sidebar-link">Fluent API</a></li><li><a href="/javascript/web-cryptography-api.html" class="sidebar-link">Web Cryptography API</a></li><li><a href="/javascript/security-issues.html" class="sidebar-link">Security issues</a></li><li><a href="/javascript/same-origin-policy-cross-origin-communication.html" class="sidebar-link">Same Origin Policy & Cross-Origin Communication</a></li><li><a href="/javascript/error-handling.html" class="sidebar-link">Error Handling</a></li><li><a href="/javascript/global-error-handling-in-browsers.html" class="sidebar-link">Global error handling in browsers</a></li><li><a href="/javascript/debugging.html" class="sidebar-link">Debugging</a></li><li><a href="/javascript/unit-testing-javascript.html" class="sidebar-link">Unit Testing Javascript</a></li><li><a href="/javascript/evaluating-javascript.html" class="sidebar-link">Evaluating JavaScript</a></li><li><a href="/javascript/linters-ensuring-code-quality.html" class="sidebar-link">Linters - Ensuring code quality</a></li><li><a href="/javascript/anti-patterns.html" class="sidebar-link">Anti-patterns</a></li><li><a href="/javascript/performance-tips.html" class="sidebar-link">Performance Tips</a></li><li><a href="/javascript/memory-efficiency.html" class="sidebar-link">Memory efficiency</a></li><li><a href="/javascript/reserved-keywords.html" class="sidebar-link">Reserved Keywords</a></li><li><a href="/javascript/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="comparison-operations"><a href="#comparison-operations" class="header-anchor">#</a> Comparison Operations</h1> <h2 id="abstract-equality-inequality-and-type-conversion"><a href="#abstract-equality-inequality-and-type-conversion" class="header-anchor">#</a> Abstract equality / inequality and type conversion</h2> <h3 id="the-problem"><a href="#the-problem" class="header-anchor">#</a> The Problem</h3> <p>The abstract equality and inequality operators (<code>==</code> and <code>!=</code>) convert their operands if the operand types do not match. This type coercion is a common source of confusion about the results of these operators, in particular, these operators aren't always transitive as one would expect.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token string">""</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true A</span>
<span class="token number">0</span> <span class="token operator">==</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// true A</span>
<span class="token string">""</span> <span class="token operator">==</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// false B</span>
<span class="token boolean">false</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token boolean">false</span> <span class="token operator">==</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token string">""</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false A</span>
<span class="token number">0</span> <span class="token operator">!=</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// false A</span>
<span class="token string">""</span> <span class="token operator">!=</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// true B</span>
<span class="token boolean">false</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">!=</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>The results start to make sense if you consider how JavaScript converts empty strings to numbers.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
<span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
<span class="token function">Number</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 0</span>
</code></pre></div><h3 id="the-solution"><a href="#the-solution" class="header-anchor">#</a> The Solution</h3> <p>In the statement <code>false B</code>, both the operands are strings (<code>""</code> and <code>"0"</code>), hence there will be <strong>no type conversion</strong> and since <code>""</code> and <code>"0"</code> are not the same value, <code>"" == "0"</code> is <code>false</code> as expected.</p> <p>One way to eliminate unexpected behavior here is making sure that you always compare operands of the same type. For example, if you want the results of numerical comparison use explicit conversion:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">test</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">Number</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token function">Number</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"abc"</span><span class="token punctuation">,</span> <span class="token string">"abc"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false as operands are not numbers </span>
</code></pre></div><p>Or, if you want string comparison:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">test</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span>b</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">String</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token function">String</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false;</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> <span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false;</span>
</code></pre></div><p><strong>Side-note</strong>: <code>Number("0")</code> and <code>new Number("0")</code> isn't the same thing! While the former performs a type conversion, the latter will create a new object. Objects are compared by reference and not by value which explains the results below.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token function">Number</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true;</span>
<span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token keyword">new</span> <span class="token class-name">Number</span><span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false </span>
</code></pre></div><p>Finally, you have the option to use strict equality and inequality operators which will not perform any implicit type conversions.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token string">""</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">0</span> <span class="token operator">===</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token string">""</span> <span class="token operator">===</span> <span class="token string">"0"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>Further reference to this topic can be found here:</p> <p><a href="http://stackoverflow.com/questions/359494/does-it-matter-which-equals-operator-vs-i-use-in-javascript-comparisons" target="_blank" rel="noopener noreferrer">Which equals operator (== vs ===) should be used in JavaScript comparisons?<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <p><a href="http://stackoverflow.com/documentation/javascript/208/comparison-operations/796/abstract-equality#t=20160804184158484392" target="_blank" rel="noopener noreferrer">Abstract Equality (==)<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="nan-property-of-the-global-object"><a href="#nan-property-of-the-global-object" class="header-anchor">#</a> NaN Property of the Global Object</h2> <p><code>NaN</code> ("<strong>N</strong>ot <strong>a</strong> <strong>N</strong>umber") is a special value defined by the <strong><a href="https://en.wikipedia.org/wiki/IEEE_floating_point" target="_blank" rel="noopener noreferrer">IEEE Standard for Floating-Point Arithmetic<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></strong>, which is used when a non-numeric value is provided but a number is expected (<code>1 * "two"</code>), or when a calculation doesn't have a valid <code>number</code> result (<code>Math.sqrt(-1)</code>).</p> <p>Any equality or relational comparisons with <code>NaN</code> returns <code>false</code>, even comparing it with itself. Because, <code>NaN</code> is supposed to denote the result of a nonsensical computation, and as such, it isn’t equal to the result of any other nonsensical computations.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">*</span> <span class="token string">"two"</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token number">NaN</span> <span class="token comment">//false</span>
<span class="token number">NaN</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">===</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token number">NaN</span> <span class="token operator">===</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator"><</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">>=</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">>=</span> <span class="token string">'two'</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>Non-equal comparisons will always return <code>true</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">NaN</span> <span class="token operator">!==</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">NaN</span> <span class="token operator">!==</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><h3 id="checking-if-a-value-is-nan"><a href="#checking-if-a-value-is-nan" class="header-anchor">#</a> Checking if a value is NaN</h3> <p>You can test a value or expression for <code>NaN</code> by using the function <a href="http://stackoverflow.com/documentation/javascript/700/built-in-constants/1760/testing-for-nan-using-isnan#t=201607302335066533303" target="_blank" rel="noopener noreferrer">Number.isNaN()<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>:</p> <div class="language-js extra-class"><pre class="language-js"><code>Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'str'</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'24'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'str'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Number<span class="token punctuation">.</span><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>You can check if a value is <code>NaN</code> by comparing it with itself:</p> <div class="language-js extra-class"><pre class="language-js"><code>value <span class="token operator">!==</span> value<span class="token punctuation">;</span> <span class="token comment">// true for NaN, false for any other value</span>
</code></pre></div><p>You can use the following polyfill for <code>Number.isNaN()</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code>Number<span class="token punctuation">.</span>isNaN <span class="token operator">=</span> Number<span class="token punctuation">.</span>isNaN <span class="token operator">||</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> value <span class="token operator">!==</span> value<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>By contrast, the global function <code>isNaN()</code> returns <code>true</code> not only for <code>NaN</code>, but also for any value or expression that cannot be coerced into a number:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">0</span> <span class="token operator">/</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'str'</span> <span class="token operator">-</span> <span class="token number">12</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">24</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'24'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token number">Infinity</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token string">'str'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token function">isNaN</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><p>ECMAScript defines a “sameness” algorithm called <code>SameValue</code> which, since ECMAScript 6, can be invoked with <code>Object.is</code>. Unlike the <code>==</code> and <code>===</code> comparison, using <code>Object.is()</code> will treat <code>NaN</code> as identical with itself (and <code>-0</code> as not identical with <code>+0</code>):</p> <div class="language-js extra-class"><pre class="language-js"><code>Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">)</span> <span class="token comment">// true</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token comment">// false</span>
<span class="token number">NaN</span> <span class="token operator">===</span> <span class="token number">NaN</span> <span class="token comment">// false</span>
<span class="token operator">+</span><span class="token number">0</span> <span class="token operator">===</span> <span class="token number">0</span> <span class="token comment">// true</span>
</code></pre></div><p>You can use the following polyfill for <code>Object.is()</code> (from <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill_for_non-ES6_browsers" target="_blank" rel="noopener noreferrer">MDN<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>):</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Object<span class="token punctuation">.</span>is<span class="token punctuation">)</span> <span class="token punctuation">{</span>
Object<span class="token punctuation">.</span><span class="token function-variable function">is</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// SameValue algorithm</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">===</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Steps 1-5, 7-10</span>
<span class="token comment">// Steps 6.b-6.e: +0 != -0</span>
<span class="token keyword">return</span> x <span class="token operator">!==</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token number">1</span> <span class="token operator">/</span> x <span class="token operator">===</span> <span class="token number">1</span> <span class="token operator">/</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// Step 6.a: NaN == NaN</span>
<span class="token keyword">return</span> x <span class="token operator">!==</span> x <span class="token operator">&&</span> y <span class="token operator">!==</span> y<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="points-to-note"><a href="#points-to-note" class="header-anchor">#</a> Points to note</h3> <p>NaN itself is a number, meaning that it does not equal to the string "NaN", and most importantly (though perhaps unintuitively):</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token string">"number"</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
</code></pre></div><h2 id="short-circuiting-in-boolean-operators"><a href="#short-circuiting-in-boolean-operators" class="header-anchor">#</a> Short-circuiting in boolean operators</h2> <p>The and-operator (<code>&&</code>) and the or-operator (<code>||</code>) employ short-circuiting to prevent unnecessary work if the outcome of the operation does not change with the extra work.</p> <p>In <code>x && y</code>, <code>y</code> will not be evaluated if <code>x</code> evaluates to <code>false</code>, because the whole expression is guaranteed to be <code>false</code>.</p> <p>In <code>x || y</code>, <code>y</code> will not be evaluated if <code>x</code> evaluated to <code>true</code>, because the whole expression is guaranteed to be <code>true</code>.</p> <p><strong>Example with functions</strong></p> <p>Take the following two functions:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token constant">T</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// True</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"T"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// False</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"F"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong><strong>Example 1</strong></strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">T</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>Output:</p> <blockquote></blockquote> <p>'T'<br>
'F'</p> <p><strong><strong>Example 2</strong></strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token constant">T</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>Output:</p> <blockquote></blockquote> <p>'F'</p> <p><strong><strong>Example 3</strong></strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">T</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><p>Output:</p> <blockquote></blockquote> <p>'T'</p> <p><strong><strong>Example 4</strong></strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">F</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token constant">T</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><p>Output:</p> <blockquote></blockquote> <p>'F'<br>
'T'</p> <p><strong>Short-circuiting to prevent errors</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> obj<span class="token punctuation">;</span> <span class="token comment">// object has value of undefined</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>property<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token comment">// TypeError: Cannot read property 'property' of undefined</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>property <span class="token operator">&&</span> obj <span class="token operator">!==</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment">// Line A TypeError: Cannot read property 'property' of undefined</span>
</code></pre></div><p>Line A: if you reverse the order the first conditional statement will prevent the error on the second by not executing it if it would throw the error</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span><span class="token punctuation">(</span>obj <span class="token operator">!==</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span> obj<span class="token punctuation">.</span>property<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// no error thrown </span>
</code></pre></div><p>But should only be used if you expect <code>undefined</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> obj <span class="token operator">===</span> <span class="token string">"object"</span> <span class="token operator">&&</span> obj<span class="token punctuation">.</span>property<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// safe option but slower</span>
</code></pre></div><p><strong>Short-circuiting to provide a default value</strong></p> <p>The <code>||</code> operator can be used to select either a "truthy" value, or the default value.</p> <p>For example, this can be used to ensure that a nullable value is converted to a non-nullable value:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> nullableObj <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> obj <span class="token operator">=</span> nullableObj <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// this selects {}</span>
<span class="token keyword">var</span> nullableObj2 <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> obj2 <span class="token operator">=</span> nullableObj2 <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> <span class="token comment">// this selects {x: 5}</span>
</code></pre></div><p>Or to return the first truthy value</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> truthyValue <span class="token operator">=</span> <span class="token punctuation">{</span>x<span class="token operator">:</span> <span class="token number">10</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> truthyValue <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// will return {x: 10}</span>
</code></pre></div><p>The same can be used to fall back multiple times:</p> <div class="language-js extra-class"><pre class="language-js"><code>envVariable <span class="token operator">||</span> configValue <span class="token operator">||</span> defaultConstValue <span class="token comment">// select the first "truthy" of these</span>
</code></pre></div><p><strong>Short-circuiting to call an optional function</strong></p> <p>The <code>&&</code> operator can be used to evaluate a callback, only if it is passed:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">myMethod</span><span class="token punctuation">(</span><span class="token parameter">cb</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// This can be simplified</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>cb<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">cb</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// To this</span>
cb <span class="token operator">&&</span> <span class="token function">cb</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Of course, the test above does not validate that <code>cb</code> is in fact a <code>function</code> and not just an <code>Object</code>/<code>Array</code>/<code>String</code>/<code>Number</code>.</p> <h2 id="abstract-equality"><a href="#abstract-equality" class="header-anchor">#</a> Abstract Equality (==)</h2> <p>Operands of the abstract equality operator are compared <strong>after</strong> being converted to a common type. How this conversion happens is based on the specification of the operator:</p> <p><a href="https://tc39.github.io/ecma262/#sec-abstract-equality-comparison" target="_blank" rel="noopener noreferrer">Specification for the <code>==</code> operator:<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <blockquote></blockquote> <p></p><h3>7.2.13 Abstract Equality Comparison</h3>
The comparison `x == y`, where `x` and `y` are values, produces `true` or `false`. Such a comparison is performed as follows:<p></p> <ol>
- If `Type(x)` is the same as `Type(y)`, then:
</ol> <ul>
- **a.** Return the result of performing Strict Equality Comparison `x === y`.
</ul> <ol start="2">
- If `x` is `null` and `y` is `undefined`, return `true`.
- If `x` is `undefined` and `y` is `null`, return `true`.
- If `Type(x)` is `Number` and `Type(y)` is `String`, return the result of the comparison `x == ToNumber(y)`.
- If `Type(x)` is `String` and `Type(y)` is `Number`, return the result of the comparison `ToNumber(x) == y`.
- If `Type(x)` is `Boolean`, return the result of the comparison `ToNumber(x) == y`.
- If `Type(y)` is `Boolean`, return the result of the `comparison x == ToNumber(y)`.
- If `Type(x)` is either `String`, `Number`, or `Symbol` and `Type(y)` is `Object`, return the result of the comparison `x == ToPrimitive(y)`.
- If `Type(x)` is Object and `Type(y)` is either `String`, `Number`, or `Symbol`, return the result of the comparison `ToPrimitive(x) == y`.
- Return `false`.
</ol> <h3 id="examples"><a href="#examples" class="header-anchor">#</a> Examples:</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token comment">// true (operand converted to number: true => 1)</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token string">'1'</span><span class="token punctuation">;</span> <span class="token comment">// true (operand converted to number: '1' => 1 )</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token string">'1.00'</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token string">'1.00000000001'</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token string">'1.00000000000000001'</span><span class="token punctuation">;</span> <span class="token comment">// true (true due to precision loss)</span>
<span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// true (spec #2)</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">0</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">0</span> <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">0</span> <span class="token operator">==</span> <span class="token string">""</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><h2 id="null-and-undefined"><a href="#null-and-undefined" class="header-anchor">#</a> Null and Undefined</h2> <h3 id="the-differences-between-null-and-undefined"><a href="#the-differences-between-null-and-undefined" class="header-anchor">#</a> The differences between <code>null</code> and <code>undefined</code></h3> <p><code>null</code> and <code>undefined</code> share abstract equality <code>==</code> but not strict equality <code>===</code>,</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span> <span class="token comment">// true</span>
<span class="token keyword">null</span> <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token comment">// false</span>
</code></pre></div><p>They represent slightly different things:</p> <ul><li><code>undefined</code> represents the <strong>absence of a value</strong>, such as before an identifier/Object property has been created or in the period between identifier/Function parameter creation and it's first set, if any.</li> <li><code>null</code> represents the <strong><strong>intentional</strong> absence of a value</strong> for an identifier or property which has already been created.</li></ul> <p>They are different types of syntax:</p> <ul><li><code>undefined</code> is a <strong>property of the global Object</strong>, usually immutable in the global scope. This means anywhere you can define an identifier other than in the global namespace could hide <code>undefined</code> from that scope (although things can still <strong>be</strong> <code>undefined</code>)</li> <li><code>null</code> is a <strong>word literal</strong>, so it's meaning can never be changed and attempting to do so will throw an <strong>Error</strong>.</li></ul> <h3 id="the-similarities-between-null-and-undefined"><a href="#the-similarities-between-null-and-undefined" class="header-anchor">#</a> The similarities between <code>null</code> and <code>undefined</code></h3> <p><code>null</code> and <code>undefined</code> are both falsy.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"won't be logged"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"won't be logged"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Neither <code>null</code> or <code>undefined</code> equal <code>false</code> (see <a href="http://stackoverflow.com/q/19277458/220060" target="_blank" rel="noopener noreferrer">this question<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>).</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token boolean">false</span> <span class="token operator">==</span> <span class="token keyword">undefined</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">===</span> <span class="token keyword">undefined</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">===</span> <span class="token keyword">null</span> <span class="token comment">// false</span>
</code></pre></div><h3 id="using-undefined"><a href="#using-undefined" class="header-anchor">#</a> Using <code>undefined</code></h3> <ul><li>If the current scope can't be trusted, use something which evaluates to <strong>undefined</strong>, for example <code>void 0;</code>.</li> <li>If <code>undefined</code> is shadowed by another value, it's just as bad as shadowing <code>Array</code> or <code>Number</code>.</li> <li>Avoid <strong>setting</strong> something as <code>undefined</code>. If you want to remove a property <strong>bar</strong> from an <strong>Object</strong> <code>foo</code>, <code>delete foo.bar;</code> instead.</li> <li>Existence testing identifier <code>foo</code> against <code>undefined</code> <strong>could throw a Reference Error</strong>, use <code>typeof foo</code> against <code>"undefined"</code> instead.</li></ul> <h2 id="logic-operators-with-booleans"><a href="#logic-operators-with-booleans" class="header-anchor">#</a> Logic Operators with Booleans</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
y <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="and"><a href="#and" class="header-anchor">#</a> AND</h3> <p>This operator will return true if both of the expressions evaluate to true. This boolean operator will employ short-circuiting and will not evaluate <code>y</code> if <code>x</code> evaluates to <code>false</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code>x <span class="token operator">&&</span> y<span class="token punctuation">;</span>
</code></pre></div><p>This will return false, because <code>y</code> is false.</p> <h3 id="or"><a href="#or" class="header-anchor">#</a> OR</h3> <p>This operator will return true if one of the two expressions evaluate to true. This boolean operator will employ short-circuiting and <code>y</code> will not be evaluated if <code>x</code> evaluates to <code>true</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code>x <span class="token operator">||</span> y<span class="token punctuation">;</span>
</code></pre></div><p>This will return true, because <code>x</code> is true.</p> <h3 id="not"><a href="#not" class="header-anchor">#</a> NOT</h3> <p>This operator will return false if the expression on the right evaluates to true, and return true if the expression on the right evaluates to false.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">!</span>x<span class="token punctuation">;</span>
</code></pre></div><p>This will return false, because <code>x</code> is true.</p> <h2 id="logic-operators-with-non-boolean-values-boolean-coercion"><a href="#logic-operators-with-non-boolean-values-boolean-coercion" class="header-anchor">#</a> Logic Operators with Non-boolean values (boolean coercion)</h2> <p>Logical OR (<code>||</code>), reading left to right, will evaluate to the first <strong>truthy</strong> value. If no <strong>truthy</strong> value is found, the last value is returned.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token string">'hello'</span> <span class="token operator">||</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token comment">// a = 'hello'</span>
<span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token string">''</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// b = []</span>
<span class="token keyword">var</span> c <span class="token operator">=</span> <span class="token string">''</span> <span class="token operator">||</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// c = undefined</span>
<span class="token keyword">var</span> d <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">||</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// d = 1</span>
<span class="token keyword">var</span> e <span class="token operator">=</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// e = {}</span>
<span class="token keyword">var</span> f <span class="token operator">=</span> <span class="token number">0</span> <span class="token operator">||</span> <span class="token string">''</span> <span class="token operator">||</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// f = 5</span>
<span class="token keyword">var</span> g <span class="token operator">=</span> <span class="token string">''</span> <span class="token operator">||</span> <span class="token string">'yay'</span> <span class="token operator">||</span> <span class="token string">'boo'</span><span class="token punctuation">;</span> <span class="token comment">// g = 'yay'</span>
</code></pre></div><p>Logical AND (<code>&&</code>), reading left to right, will evaluate to the first <strong>falsy</strong> value. If no <strong>falsey</strong> value is found, the last value is returned.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token string">'hello'</span> <span class="token operator">&&</span> <span class="token string">''</span><span class="token punctuation">;</span> <span class="token comment">// a = ''</span>
<span class="token keyword">var</span> b <span class="token operator">=</span> <span class="token string">''</span> <span class="token operator">&&</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// b = ''</span>
<span class="token keyword">var</span> c <span class="token operator">=</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// c = undefined</span>
<span class="token keyword">var</span> d <span class="token operator">=</span> <span class="token number">1</span> <span class="token operator">&&</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// d = 5</span>
<span class="token keyword">var</span> e <span class="token operator">=</span> <span class="token number">0</span> <span class="token operator">&&</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token comment">// e = 0</span>
<span class="token keyword">var</span> f <span class="token operator">=</span> <span class="token string">'hi'</span> <span class="token operator">&&</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">&&</span> <span class="token string">'done'</span><span class="token punctuation">;</span> <span class="token comment">// f = 'done'</span>
<span class="token keyword">var</span> g <span class="token operator">=</span> <span class="token string">'bye'</span> <span class="token operator">&&</span> <span class="token keyword">undefined</span> <span class="token operator">&&</span> <span class="token string">'adios'</span><span class="token punctuation">;</span> <span class="token comment">// g = undefined</span>
</code></pre></div><p>This trick can be used, for example, to set a default value to a function argument (prior to ES6).</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> <span class="token function-variable function">foo</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">val</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// if val evaluates to falsey, 'default' will be returned instead.</span>
<span class="token keyword">return</span> val <span class="token operator">||</span> <span class="token string">'default'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token string">'burger'</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// burger</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 100</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// []</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// default</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// default</span>
</code></pre></div><p>Just keep in mind that for arguments, <code>0</code> and (to a lesser extent) the empty string are also often valid values that should be able to be explicitly passed and override a default, which, with this pattern, they won’t (because they are <strong>falsy</strong>).</p> <h2 id="empty-array"><a href="#empty-array" class="header-anchor">#</a> Empty Array</h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">/* ToNumber(ToPrimitive([])) == ToNumber(false) */</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token boolean">false</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><p>When <code>[].toString()</code> is executed it calls <code>[].join()</code> if it exists, or <code>Object.prototype.toString()</code> otherwise. This comparison is returning <code>true</code> because <code>[].join()</code> returns <code>''</code> which, coerced into <code>0</code>, is equal to false <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-9.3" target="_blank" rel="noopener noreferrer">ToNumber<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>.</p> <p>Beware though, all objects are truthy and <code>Array</code> is an instance of <code>Object</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Internally this is evaluated as ToBoolean([]) === true ? 'truthy' : 'falsy'</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">?</span> <span class="token string">'truthy'</span> <span class="token operator">:</span> <span class="token string">'falsy'</span><span class="token punctuation">;</span> <span class="token comment">// 'truthy'</span>
</code></pre></div><h2 id="automatic-type-conversions"><a href="#automatic-type-conversions" class="header-anchor">#</a> Automatic Type Conversions</h2> <p>Beware that numbers can accidentally be converted to strings or NaN (Not a Number).</p> <p>JavaScript is loosely typed. A variable can contain different data types, and a variable can change its data type:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token string">"Hello"</span><span class="token punctuation">;</span> <span class="token comment">// typeof x is a string</span>
x <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token comment">// changes typeof x to a number</span>
</code></pre></div><p>When doing mathematical operations, JavaScript can convert numbers to strings:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is 12, typeof x is a number</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">+</span> <span class="token string">"7"</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is 57, typeof x is a string</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token string">"5"</span> <span class="token operator">+</span> <span class="token number">7</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is 57, typeof x is a string</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">-</span> <span class="token number">7</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is -2, typeof x is a number</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">-</span> <span class="token string">"7"</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is -2, typeof x is a number</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token string">"5"</span> <span class="token operator">-</span> <span class="token number">7</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is -2, typeof x is a number</span>
<span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token number">5</span> <span class="token operator">-</span> <span class="token string">"x"</span><span class="token punctuation">;</span> <span class="token comment">// x.valueOf() is NaN, typeof x is a number</span>
</code></pre></div><p>Subtracting a string from a string, does not generate an error but returns NaN (Not a Number):</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token string">"Hello"</span> <span class="token operator">-</span> <span class="token string">"Dolly"</span> <span class="token comment">// returns NaN</span>
</code></pre></div><h2 id="equality-comparison-operations"><a href="#equality-comparison-operations" class="header-anchor">#</a> Equality comparison operations</h2> <p>JavaScript has four different equality comparison operations.</p> <h3 id="samevalue"><a href="#samevalue" class="header-anchor">#</a> <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-samevalue" target="_blank" rel="noopener noreferrer"><strong>SameValue</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></h3> <p>It returns <code>true</code> if both operands belong to the same Type and are the same value.</p> <p>Note: the value of an object is a reference.</p> <p>You can use this comparison algorithm via <code>Object.is</code> (ECMAScript 6).</p> <p>Examples:</p> <div class="language-js extra-class"><pre class="language-js"><code>Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token operator">+</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">,</span> <span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token string">"true"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
Object<span class="token punctuation">.</span><span class="token function">is</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>This algorithm has the properties of an <a href="https://en.wikipedia.org/wiki/Equivalence_relation" target="_blank" rel="noopener noreferrer">equivalence relation<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>:</p> <ul><li><a href="https://en.wikipedia.org/wiki/Reflexive_relation" target="_blank" rel="noopener noreferrer">Reflexivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>Object.is(x, x)</code> is <code>true</code>, for any value <code>x</code></li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Symmetry<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>Object.is(x, y)</code> is <code>true</code> if, and only if, <code>Object.is(y, x)</code> is <code>true</code>, for any values <code>x</code> and <code>y</code>.</li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Transitivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: If <code>Object.is(x, y)</code> and <code>Object.is(y, z)</code> are <code>true</code>, then <code>Object.is(x, z)</code> is also <code>true</code>, for any values <code>x</code>, <code>y</code> and <code>z</code>.</li></ul> <h3 id="samevaluezero"><a href="#samevaluezero" class="header-anchor">#</a> <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero" target="_blank" rel="noopener noreferrer"><strong>SameValueZero</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></h3> <p>It behaves like SameValue, but considers <code>+0</code> and <code>-0</code> to be equal.</p> <p>You can use this comparison algorithm via <code>Array.prototype.includes</code> (ECMAScript 7).</p> <p>Examples:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token punctuation">[</span><span class="token operator">+</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token punctuation">[</span><span class="token number">NaN</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token number">NaN</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token punctuation">[</span><span class="token boolean">true</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"true"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token punctuation">[</span><span class="token boolean">false</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token punctuation">[</span><span class="token keyword">null</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>This algorithm still has the properties of an <a href="https://en.wikipedia.org/wiki/Equivalence_relation" target="_blank" rel="noopener noreferrer">equivalence relation<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>:</p> <ul><li><a href="https://en.wikipedia.org/wiki/Reflexive_relation" target="_blank" rel="noopener noreferrer">Reflexivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>[x].includes(x)</code> is <code>true</code>, for any value <code>x</code></li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Symmetry<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>[x].includes(y)</code> is <code>true</code> if, and only if, <code>[y].includes(x)</code> is <code>true</code>, for any values <code>x</code> and <code>y</code>.</li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Transitivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: If <code>[x].includes(y)</code> and <code>[y].includes(z)</code> are <code>true</code>, then <code>[x].includes(z)</code> is also <code>true</code>, for any values <code>x</code>, <code>y</code> and <code>z</code>.</li></ul> <h3 id="strict-equality-comparison"><a href="#strict-equality-comparison" class="header-anchor">#</a> <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-strict-equality-comparison" target="_blank" rel="noopener noreferrer"><strong>Strict Equality Comparison</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></h3> <p>It behaves like SameValue, but</p> <ul><li>Considers <code>+0</code> and <code>-0</code> to be equal.</li> <li>Considers <code>NaN</code> different than any value, including itself</li></ul> <p>You can use this comparison algorithm via the <code>===</code> operator (ECMAScript 3).</p> <p>There is also the <code>!==</code> operator (ECMAScript 3), which negates the result of <code>===</code>.</p> <p>Examples:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">===</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token operator">+</span><span class="token number">0</span> <span class="token operator">===</span> <span class="token operator">-</span><span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">NaN</span> <span class="token operator">===</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token boolean">true</span> <span class="token operator">===</span> <span class="token string">"true"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">===</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">===</span> <span class="token string">"1"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token keyword">null</span> <span class="token operator">===</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">===</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>This algorithm has the following properties:</p> <ul><li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Symmetry<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>x === y</code> is <code>true</code> if, and only if, y === x<code>is</code>true<code>, for any values</code>x<code>and</code>y`.</li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Transitivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: If <code>x === y</code> and <code>y === z</code> are <code>true</code>, then <code>x === z</code> is also <code>true</code>, for any values <code>x</code>, <code>y</code> and <code>z</code>.</li></ul> <p>But is not an <a href="https://en.wikipedia.org/wiki/Equivalence_relation" target="_blank" rel="noopener noreferrer">equivalence relation<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> because</p> <ul><li><code>NaN</code> is not <a href="https://en.wikipedia.org/wiki/Reflexive_relation" target="_blank" rel="noopener noreferrer">reflexive<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>NaN !== NaN</code></li></ul> <h3 id="abstract-equality-comparison"><a href="#abstract-equality-comparison" class="header-anchor">#</a> <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-abstract-equality-comparison" target="_blank" rel="noopener noreferrer"><strong>Abstract Equality Comparison</strong><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></h3> <p>If both operands belong to the same Type, it behaves like the Strict Equality Comparison.</p> <p>Otherwise, it coerces them as follows:</p> <ul><li><code>undefined</code> and <code>null</code> are considered to be equal</li> <li>When comparing a number with a string, the string is coerced to a number</li> <li>When comparing a boolean with something else, the boolean is coerced to a number</li> <li>When comparing an object with a number, string or symbol, the object is coerced to a primitive</li></ul> <p>If there was a coercion, the coerced values are compared recursively. Otherwise the algorithm returns <code>false</code>.</p> <p>You can use this comparison algorithm via the <code>==</code> operator (ECMAScript 1).</p> <p>There is also the <code>!=</code> operator (ECMAScript 1), which negates the result of <code>==</code>.</p> <p>Examples:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token operator">+</span><span class="token number">0</span> <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">NaN</span> <span class="token operator">==</span> <span class="token number">NaN</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token boolean">true</span> <span class="token operator">==</span> <span class="token string">"true"</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
<span class="token boolean">false</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator">==</span> <span class="token string">"1"</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token keyword">null</span> <span class="token operator">==</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// false</span>
</code></pre></div><p>This algorithm has the following property:</p> <ul><li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Symmetry<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>x == y</code> is <code>true</code> if, and only if, <code>y == x</code> is <code>true</code>, for any values <code>x</code> and <code>y</code>.</li></ul> <p>But is not an <a href="https://en.wikipedia.org/wiki/Equivalence_relation" target="_blank" rel="noopener noreferrer">equivalence relation<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> because</p> <ul><li><code>NaN</code> is not <a href="https://en.wikipedia.org/wiki/Reflexive_relation" target="_blank" rel="noopener noreferrer">reflexive<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>: <code>NaN != NaN</code></li> <li><a href="https://en.wikipedia.org/wiki/Symmetric_relation" target="_blank" rel="noopener noreferrer">Transitivity<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> does not hold, e.g. <code>0 == ''</code> and <code>0 == '0'</code>, but <code>'' != '0'</code></li></ul> <h2 id="relational-operators"><a href="#relational-operators" class="header-anchor">#</a> Relational operators (<, <=, >, >=)</h2> <p>When both operands are numeric, they are compared normally:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator"><</span> <span class="token number">2</span> <span class="token comment">// true</span>
<span class="token number">2</span> <span class="token operator"><=</span> <span class="token number">2</span> <span class="token comment">// true</span>
<span class="token number">3</span> <span class="token operator">>=</span> <span class="token number">5</span> <span class="token comment">// false</span>
<span class="token boolean">true</span> <span class="token operator"><</span> <span class="token boolean">false</span> <span class="token comment">// false (implicitly converted to numbers, 1 > 0)</span>
</code></pre></div><p>When both operands are strings, they are compared lexicographically (according to alphabetical order):</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token string">'a'</span> <span class="token operator"><</span> <span class="token string">'b'</span> <span class="token comment">// true</span>
<span class="token string">'1'</span> <span class="token operator"><</span> <span class="token string">'2'</span> <span class="token comment">// true</span>
<span class="token string">'100'</span> <span class="token operator">></span> <span class="token string">'12'</span> <span class="token comment">// false ('100' is less than '12' lexicographically!)</span>
</code></pre></div><p>When one operand is a string and the other is a number, the string is converted to a number before comparison:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token string">'1'</span> <span class="token operator"><</span> <span class="token number">2</span> <span class="token comment">// true</span>
<span class="token string">'3'</span> <span class="token operator">></span> <span class="token number">2</span> <span class="token comment">// true</span>
<span class="token boolean">true</span> <span class="token operator">></span> <span class="token string">'2'</span> <span class="token comment">// false (true implicitly converted to number, 1 < 2)</span>
</code></pre></div><p>When the string is non-numeric, numeric conversion returns <code>NaN</code> (not-a-number). Comparing with <code>NaN</code> always returns <code>false</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator"><</span> <span class="token string">'abc'</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">></span> <span class="token string">'abc'</span> <span class="token comment">// false</span>
</code></pre></div><p>But be careful when comparing a numeric value with <code>null</code>, <code>undefined</code> or empty strings:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">></span> <span class="token string">''</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator"><</span> <span class="token string">''</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">></span> <span class="token keyword">null</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator"><</span> <span class="token keyword">null</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">></span> <span class="token keyword">undefined</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator"><</span> <span class="token keyword">undefined</span> <span class="token comment">// false</span>
</code></pre></div><p>When one operand is a object and the other is a number, the object is converted to a number before comparison.So <code>null</code> is particular case because <code>Number(null);//0</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token number">2015</span><span class="token punctuation">)</span><span class="token operator"><</span> <span class="token number">1479480185280</span> <span class="token comment">// true</span>
<span class="token keyword">null</span> <span class="token operator">></span> <span class="token operator">-</span><span class="token number">1</span> <span class="token comment">//true</span>
<span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token function-variable function">toString</span><span class="token operator">:</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> <span class="token number">123</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">122</span> <span class="token comment">//true</span>
</code></pre></div><h2 id="inequality"><a href="#inequality" class="header-anchor">#</a> Inequality</h2> <p>Operator <code>!=</code> is the inverse of the <code>==</code> operator.<br>
Will return <code>true</code> if the operands aren't equal.<br>
The javascript engine will try and convert both operands to matching types if they aren't of the same type.
<strong>Note:</strong> if the two operands have different internal references in memory, then <code>false</code> will be returned.</p> <p><strong>Sample:</strong></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">!=</span> <span class="token string">'1'</span> <span class="token comment">// false</span>
<span class="token number">1</span> <span class="token operator">!=</span> <span class="token number">2</span> <span class="token comment">// true</span>
</code></pre></div><p>In the sample above, <code>1 != '1'</code> is <code>false</code> because, a primitive number type is being compared to a <code>char</code> value. Therefore, the Javascript engine doesn't care about the datatype of the R.H.S value.</p> <p>Operator: <code>!==</code> is the inverse of the <code>===</code> operator.
Will return true if the operands are not equal or if their types do not match.</p> <p>Example:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token number">1</span> <span class="token operator">!==</span> <span class="token string">'1'</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator">!==</span> <span class="token number">2</span> <span class="token comment">// true</span>
<span class="token number">1</span> <span class="token operator">!==</span> <span class="token number">1</span> <span class="token comment">// false</span>
</code></pre></div><h2 id="grouping-multiple-logic-statements"><a href="#grouping-multiple-logic-statements" class="header-anchor">#</a> Grouping multiple logic statements</h2> <p>You can group multiple boolean logic statements within parenthesis in order to create a more complex logic evaluation, especially useful in if statements.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>age <span class="token operator">>=</span> <span class="token number">18</span> <span class="token operator">&&</span> height <span class="token operator">>=</span> <span class="token number">5.11</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token punctuation">(</span>status <span class="token operator">===</span> <span class="token string">'royalty'</span> <span class="token operator">&&</span> hasInvitation<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'You can enter our club'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>We could also move the grouped logic to variables to make the statement a bit shorter and descriptive:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> isLegal <span class="token operator">=</span> age <span class="token operator">>=</span> <span class="token number">18</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> tall <span class="token operator">=</span> height <span class="token operator">>=</span> <span class="token number">5.11</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> suitable <span class="token operator">=</span> isLegal <span class="token operator">&&</span> tall<span class="token punctuation">;</span>
<span class="token keyword">var</span> isRoyalty <span class="token operator">=</span> status <span class="token operator">===</span> <span class="token string">'royalty'</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> specialCase <span class="token operator">=</span> isRoyalty <span class="token operator">&&</span> hasInvitation<span class="token punctuation">;</span>
<span class="token keyword">var</span> canEnterOurBar <span class="token operator">=</span> suitable <span class="token operator">||</span> specialCase<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>canEnterOurBar<span class="token punctuation">)</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'You can enter our club'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Notice that in this particular example (and many others), grouping the statements with parenthesis works the same as if we removed them, just follow a linear logic evaluation and you'll find yourself with the same result. I do prefer using parenthesis as it allows me to understand clearer what I intended and might prevent for logic mistakes.</p> <h2 id="list-of-comparison-operators"><a href="#list-of-comparison-operators" class="header-anchor">#</a> List of Comparison Operators</h2> <table><thead><tr><th>Operator</th> <th>Comparison</th> <th>Example</th></tr></thead> <tbody><tr><td><code>==</code></td> <td>Equal</td> <td><code>i == 0</code></td></tr> <tr><td><code>===</code></td> <td>Equal Value and Type</td> <td><code>i === "5"</code></td></tr> <tr><td><code>!=</code></td> <td>Not Equal</td> <td><code>i != 5</code></td></tr> <tr><td><code>!==</code></td> <td>Not Equal Value or Type</td> <td><code>i !== 5</code></td></tr> <tr><td><code>></code></td> <td>Greater than</td> <td><code>i > 5</code></td></tr> <tr><td><code><</code></td> <td>Less than</td> <td><code>i < 5</code></td></tr> <tr><td><code>>=</code></td> <td>Greater than or equal</td> <td><code>i >= 5</code></td></tr> <tr><td><code><=</code></td> <td>Less than or equal</td> <td><code>i <= 5</code></td></tr></tbody></table> <h2 id="bit-fields-to-optimise-comparison-of-multi-state-data"><a href="#bit-fields-to-optimise-comparison-of-multi-state-data" class="header-anchor">#</a> Bit fields to optimise comparison of multi state data</h2> <p>A bit field is a variable that holds various boolean states as individual bits. A bit on would represent true, and off would be false. In the past bit fields were routinely used as they saved memory and reduced processing load. Though the need to use bit field is no longer so important they do offer some benefits that can simplify many processing tasks.</p> <p>For example user input. When getting input from a keyboard's direction keys up, down, left,right you can encode the various keys into a single variable with each direction assigned a bit.</p> <p>Example reading keyboard via bitfield</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> bitField <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// the value to hold the bits</span>
<span class="token keyword">const</span> <span class="token constant">KEY_BITS</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">8</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// left up right down</span>
<span class="token keyword">const</span> <span class="token constant">KEY_MASKS</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">0b1011</span><span class="token punctuation">,</span><span class="token number">0b1110</span><span class="token punctuation">,</span><span class="token number">0b0111</span><span class="token punctuation">,</span><span class="token number">0b1101</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">// left up right down</span>
window<span class="token punctuation">.</span>onkeydown <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function-variable function">onkeyup</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>keyCode <span class="token operator">>=</span> <span class="token number">37</span> <span class="token operator">&&</span> e<span class="token punctuation">.</span>keyCode <span class="token operator"><</span><span class="token number">41</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">"keydown"</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
bitField <span class="token operator">|=</span> <span class="token constant">KEY_BITS</span><span class="token punctuation">[</span>e<span class="token punctuation">.</span>keyCode <span class="token operator">-</span> <span class="token number">37</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">else</span><span class="token punctuation">{</span>
bitField <span class="token operator">&=</span> <span class="token constant">KEY_MASKS</span><span class="token punctuation">[</span>e<span class="token punctuation">.</span>keyCode <span class="token operator">-</span> <span class="token number">37</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Example reading as an array</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> directionState <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token boolean">false</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">,</span><span class="token boolean">false</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
window<span class="token punctuation">.</span>onkeydown <span class="token operator">=</span> window<span class="token punctuation">.</span><span class="token function-variable function">onkeyup</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>keyCode <span class="token operator">>=</span> <span class="token number">37</span> <span class="token operator">&&</span> e<span class="token punctuation">.</span>keyCode <span class="token operator"><</span><span class="token number">41</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
directionState<span class="token punctuation">[</span>e<span class="token punctuation">.</span>keyCode <span class="token operator">-</span> <span class="token number">37</span><span class="token punctuation">]</span> <span class="token operator">=</span> e<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">"keydown"</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>To turn on a bit use bitwise <strong>or</strong> <code>|</code> and the value corresponding to the bit. So if you wish to set the 2nd bit <code>bitField |= 0b10</code> will turn it on. If you wish to turn a bit off use bitwise <strong>and</strong> <code>&</code> with a value that has all by the required bit on. Using 4 bits and turning the 2nd bit off <code>bitfield &= 0b1101;</code></p> <p>You may say the above example seems a lot more complex than assigning the various key states to a array. Yes It is a little more complex to set but the advantage comes when interrogating the state.</p> <p>If you want to test if all keys are up.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// as bit field</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>bitfield<span class="token punctuation">)</span> <span class="token comment">// no keys are on</span>
<span class="token comment">// as array test each item in array</span>
<span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>directionState<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&&</span> directionState<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">&&</span> directionState<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">&&</span> directionState<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
</code></pre></div><p>You can set some constants to make things easier</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// postfix U,D,L,R for Up down left right</span>
<span class="token keyword">const</span> <span class="token constant">KEY_U</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">KEY_D</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">KEY_L</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">KEY_R</span> <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">KEY_UL</span> <span class="token operator">=</span> <span class="token constant">KEY_U</span> <span class="token operator">+</span> <span class="token constant">KEY_L</span><span class="token punctuation">;</span> <span class="token comment">// up left</span>
<span class="token keyword">const</span> <span class="token constant">KEY_UR</span> <span class="token operator">=</span> <span class="token constant">KEY_U</span> <span class="token operator">+</span> <span class="token constant">KEY_R</span><span class="token punctuation">;</span> <span class="token comment">// up Right</span>
<span class="token keyword">const</span> <span class="token constant">KEY_DL</span> <span class="token operator">=</span> <span class="token constant">KEY_D</span> <span class="token operator">+</span> <span class="token constant">KEY_L</span><span class="token punctuation">;</span> <span class="token comment">// down left</span>
<span class="token keyword">const</span> <span class="token constant">KEY_DR</span> <span class="token operator">=</span> <span class="token constant">KEY_D</span> <span class="token operator">+</span> <span class="token constant">KEY_R</span><span class="token punctuation">;</span> <span class="token comment">// down right</span>
</code></pre></div><p>You can then quickly test for many various keyboard states</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>bitfield <span class="token operator">&</span> <span class="token constant">KEY_UL</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token constant">KEY_UL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// is UP and LEFT only down</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>bitfield <span class="token operator">&</span> <span class="token constant">KEY_UL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// is Up left down </span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>bitfield <span class="token operator">&</span> <span class="token constant">KEY_U</span><span class="token punctuation">)</span> <span class="token operator">===</span> <span class="token constant">KEY_U</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// is Up only down</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>bitfield <span class="token operator">&</span> <span class="token constant">KEY_U</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// is Up down (any other key may be down)</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>bitfield <span class="token operator">&</span> <span class="token constant">KEY_U</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// is Up up (any other key may be down)</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>bitfield <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// no keys are down</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>bitfield <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// any one or more keys are down</span>
</code></pre></div><p>The keyboard input is just one example. Bitfields are useful when you have various states that must in combination be acted on. Javascript can use upto 32 bits for a bit field. Using them can offer significant performance increases. They are worth being familiar with.</p> <h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p>When using boolean coercion, the following values are considered <strong>"falsy"</strong>:</p> <ul><li><code>false</code></li> <li><code>0</code></li> <li><code>""</code> (empty string)</li> <li><code>null</code></li> <li><code>undefined</code></li> <li><code>NaN</code> (not a number, e.g. <code>0/0</code>)</li> <li><code>document.all</code>¹ (browser context)</li></ul> <p>Everything else is considered <strong>"truthy"</strong>.</p> <p>¹ <sub><a href="https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-all" target="_blank" rel="noopener noreferrer">willful violation of the ECMAScript specification<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></sub></p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/javascript/comparison-operations.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/javascript/date-comparison.html" class="prev">
Date Comparison
</a></span> <span class="next"><a href="/javascript/conditions.html">
Conditions
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/1717.17528fff.js" defer></script>
</body>
</html>