annotate core-javascript/equality.rst @ 213:0ea90a1819c2 default tip

Custom theming
author Radomir Dopieralski <radomir.dopieralski@allegro.pl>
date Wed, 27 Jun 2012 16:35:54 +0200
parents a808230bc5dd
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
100
cff48ce99b1f Finished with objects.rst (at least for now).
jf3243
parents:
diff changeset
1 Equality
cff48ce99b1f Finished with objects.rst (at least for now).
jf3243
parents:
diff changeset
2 ========
103
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
3
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
4 Equality in JavaScript can be a little odd.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
5
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
6
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
7 Double equals
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
8 -------------
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
9
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
10 JavScript has two operations for equality (and inequality). One of
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
11 them is '==' (and '!=' for inequality). It's the oddest.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
12
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
13
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
14 Not transitive
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
15 ^^^^^^^^^^^^^^
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
16
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
17 If *a* is equal to *b*, and if *b* is equal to *c* , then we expect
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
18 *a* to be equal to *c*. This is called the transitive property.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
19
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
20
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
21 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
22
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
23
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
24 js> '0' == 0 // 'a' is equal to 'b'
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
25 true
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
26 js> 0 == '' // 'b' is equal to 'c'
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
27 true
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
28 js> '0' == '' // 'a' is not equal to 'c'
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
29 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
30
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
31
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
32
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
33 Not reflexive
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
34 ^^^^^^^^^^^^^
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
35
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
36 We expect *a* to be equal to *a*. This is called the reflexive
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
37 property.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
38
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
39 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
40
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
41 js> NaN == NaN
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
42 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
43
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
44 Fortunately, this seems to be the only example.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
45
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
46
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
47 Is symmetric
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
48 ^^^^^^^^^^^^
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
49
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
50 If *a* is equal to *b* then we expect *b* to be equal to *a*. This is
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
51 called the symmetric property. In JavaScript equality is symmetric.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
52
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
53
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
54
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
55 Triple equality
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
56 ---------------
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
57
205
a808230bc5dd Remove outdated facebook reference (404 error on the link)
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 204
diff changeset
58 JavaScript also has ``===`` (and ``!==`` for inequality).
103
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
59
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
60
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
61 Is transitive
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
62 ^^^^^^^^^^^^^
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
63
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
64 Unlike double equals, triple equals is always transitive.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
65
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
66 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
67
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
68 js> '0' === 0 // unequal
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
69 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
70 js> 0 === '' // unequal
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
71 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
72 js> '0' === '' // unequal
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
73 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
74
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
75
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
76 Not reflexive
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
77 ^^^^^^^^^^^^^
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
78
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
79 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
80
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
81 js> NaN === NaN
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
82 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
83
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
84
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
85 Is symmetric
130
ff23e32bbe29 Sort out table of contents, and various minor changes.
jf3243
parents: 103
diff changeset
86 ^^^^^^^^^^^^
103
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
87
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
88 Triple equality is still symmetric.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
89
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
90
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
91 Don't use double equality
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
92 -------------------------
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
93
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
94 Double equality does implicit conversions and besides has some odd
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
95 rules. My advice is **don't use double equality**.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
96
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
97 Triple equality does not do conversions. If you want to do
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
98 conversions in your comparision my advice is to make them explicit.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
99
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
100
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
101 Compare as string
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
102 -----------------
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
103
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
104 The easiest conversion is to string. Here are two immutables, a
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
105 number and a string.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
106
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
107 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
108
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
109 js> a = 0
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
110 0
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
111 js> b = '0'
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
112 0
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
113
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
114
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
115 These quantities are double equal but not triple equal.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
116
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
117 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
118
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
119 js> a == b
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
120 true
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
121 js> a === b
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
122 false
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
123
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
124 Here's how to do an explicit conversion to string before comparison,
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
125 which gives an equality.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
126
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
127 .. code-block:: javascript
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
128
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
129 js> '' + a === '' + b // Converts variables to strings.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
130 true
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
131
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
132 .. note::
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
133
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
134 It's always easier to read a triple equal comparison, because
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
135 you're not distracted by the complex double equal rules.
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
136
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
137
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
138 Compare as number
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
139 -----------------
e29fb5d95bfc Done with equality.rst (for now).
jf3243
parents: 100
diff changeset
140
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
141 There is a way to make sure that a value is a number in JavaScript:
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
142 use the unary plus operator:
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
143
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
144 .. code-block:: javascript
200
6ea48585f70c Add the missing empty lines for code blocks
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 199
diff changeset
145
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
146 js> +a === +b
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
147 true
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
148
204
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
149 When the value cannot be converted to a number, you will get a ``NaN`` value.
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
150 `NaN` is never equal to anything, even to itself.
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
151
204
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
152 Alternatively, you can use the ``parseInt`` and ``parseFloat`` functions to convert
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
153 strings to number -- their behavior is slightly different, as they will silently
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
154 ignore all non-number characters in the string.
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
155
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
156 .. code-block:: javascript
200
6ea48585f70c Add the missing empty lines for code blocks
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 199
diff changeset
157
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
158 js> parseInt('3abc1')
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
159 3
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
160 js> +'3abc1'
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
161 NaN
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
162
204
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
163 Because ``NaN`` is never equal to anything, even itself, you cannot check whether
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
164 you got ``NaN`` as a result with ``==`` or ``===``. You have to use the ``isNaN``
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
165 function for that.
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
166
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
167 Compare as boolean
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
168 ------------------
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
169
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
170 To convert an expression to a boolean value, it's most convenient to use the
204
45e7d5e8fa97 Use double backticks for inline code
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 200
diff changeset
171 ``!`` boolean negation operator twice, like this:
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
172
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
173 .. code-block:: javascript
200
6ea48585f70c Add the missing empty lines for code blocks
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 199
diff changeset
174
199
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
175 js> !!0 === !!''
25a718801405 Add "Compare as number" and "Compare as boolean"
Radomir Dopieralski <radomir.dopieralski@allegro.pl>
parents: 130
diff changeset
176 true