blob: 82b19641ea6facc97ad2fd103c95aec223957308 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
---
title: 逻辑运算符
slug: >-
conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca
tags:
- JavaScript
- 操作符
- 逻辑
translation_of: Web/JavaScript/Reference/Operators
translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators
original_slug: Web/JavaScript/Reference/Operators/Logical_Operators
---
<div>{{jsSidebar("Operators")}}</div>
<p>逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,<code>&&</code> 和 <code>||</code> 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。</p>
<div>{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}</div>
<h2 id="描述">描述</h2>
<p>逻辑运算符如下表所示 (其中<code><em>expr</em></code>可能是任何一种<a href="https://developer.mozilla.org/zh-CN/docs/Glossary/Data_structure">类型</a>, 不一定是布尔值):</p>
<table class="fullwidth-table syntaxbox">
<tbody>
<tr>
<th>运算符</th>
<th>语法</th>
<th>说明</th>
</tr>
<tr>
<td>逻辑与,AND(<code>&&</code>)</td>
<td><code><em>expr1</em> && <em>expr2</em></code></td>
<td>若 <code>expr<strong>1</strong></code> 可转换为 <code>true</code>,则返回 <code>expr<strong>2</strong></code>;否则,返回 <code>expr<strong>1</strong></code>。</td>
</tr>
<tr>
<td>逻辑或,OR(<code>||</code>)</td>
<td><code><em>expr1</em> || <em>expr2</em></code></td>
<td>若 <code>expr<strong>1</strong></code> 可转换为 <code>true</code>,则返回 <code>expr<strong>1</strong></code>;否则,返回 <code>expr<strong>2</strong></code>。</td>
</tr>
<tr>
<td>逻辑非,NOT(<code>!</code>)</td>
<td><code>!<em>expr</em></code></td>
<td>若 <code>expr</code> 可转换为 <code>true</code>,则返回 <code>false</code>;否则,返回 <code>true</code>。</td>
</tr>
</tbody>
</table>
<p>如果一个值可以被转换为 <code>true</code>,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 <code>false</code>,那么这个值就是所谓的 {{Glossary("falsy")}}。</p>
<p>会被转换为 <code>false</code> 的表达式有:</p>
<ul>
<li><code>null</code>;</li>
<li><code>NaN</code>;</li>
<li><code>0</code>;</li>
<li>空字符串(<code>""</code> or <code>''</code> or <code>``</code>);</li>
<li><code>undefined</code>。</li>
</ul>
<p>尽管 <code>&&</code> 和 <code>||</code> 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators#%E9%80%BB%E8%BE%91%E9%9D%9E%EF%BC%88!%EF%BC%89">双重非运算符</a>(即<code>!!</code>)或者<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a>构造函数。</p>
<h3 id="短路计算">短路计算</h3>
<p>由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:</p>
<ul>
<li><code>(some falsy expression) && (<em>expr)</em></code> 短路计算的结果为假。</li>
<li><code>(some truthy expression) || <em>(expr)</em></code> 短路计算的结果为真。</li>
</ul>
<p>短路意味着上述表达式中的expr部分<strong>不会被执行</strong>,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:</p>
<pre class="brush: js">function A(){ console.log('called A'); return false; }
function B(){ console.log('called B'); return true; }
console.log( A() && B() );
// logs "called A" due to the function call,
// then logs false (which is the resulting value of the operator)
console.log( B() || A() );
// logs "called B" due to the function call,
// then logs true (which is the resulting value of the operator)
</pre>
<h3 id="Operators_precedence">Operators precedence</h3>
<p>请注意,由于<a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">运算符优先级</a>的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。</p>
<pre class="brush: js">false && true || true // 结果为 true
false && (true || true) // 结果为 false
</pre>
<h3 id="逻辑与()">逻辑与(<code>&&</code>)</h3>
<p>下面的代码是 && (逻辑与) 运算符的示例.</p>
<pre class="brush: js">a1 = true && true // t && t 返回 true
a2 = true && false // t && f 返回 false
a3 = false && true // f && t 返回 false
a4 = false && (3 == 4) // f && f 返回 false
a5 = "Cat" && "Dog" // t && t 返回 "Dog"
a6 = false && "Cat" // f && t 返回 false
a7 = "Cat" && false // t && f 返回 false
a8 = '' && false // f && f 返回 ""
a9 = false && '' // f && f 返回 false
</pre>
<h3 id="逻辑或()">逻辑或(<code>||</code>)</h3>
<p>下面的代码是 || (逻辑或) 运算符的示例。</p>
<pre class="brush: js">o1 = true || true // t || t 返回 true
o2 = false || true // f || t 返回 true
o3 = true || false // t || f 返回 true
o4 = false || (3 == 4) // f || f 返回 false
o5 = "Cat" || "Dog" // t || t 返回 "Cat"
o6 = false || "Cat" // f || t 返回 "Cat"
o7 = "Cat" || false // t || f 返回 "Cat"
o8 = '' || false // f || f 返回 false
o9 = false || '' // f || f 返回 ""
</pre>
<h3 id="逻辑非(!)">逻辑非(<code>!</code>)</h3>
<p>下面的代码是 <code>!</code> (逻辑非) 运算符的示例.</p>
<pre class="brush: js">n1 = !true // !t 返回 false
n2 = !false // !f 返回 true
n3 = !'' // !f 返回 true
n4 = !'Cat' // !t 返回 false
</pre>
<h4 id="双重非(!!)运算符">双重非(<code>!!</code>)运算符</h4>
<p>可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B">布尔值</a>。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。</p>
<p>同样的转换可以通过 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a> 函数完成。</p>
<pre class="brush: js syntaxbox">n1 = !!true // !!truthy 返回 true
n2 = !!{} // !!truthy 返回 true: <strong>任何</strong> 对象都是 truthy 的…
n3 = !!(new Boolean(false)) // …甚至 <em>.valueOf()</em> 返回 false 的布尔值对象也是!
n4 = !!false // !!falsy 返回 false
n5 = !!"" // !!falsy 返回 false
n6 = !!Boolean(false) // !!falsy 返回 false
</pre>
<h3 id="布尔值转换规则">布尔值转换规则</h3>
<h4 id="将_AND_转换为_OR">将 AND 转换为 OR</h4>
<p>以下涉及<strong>布尔</strong>运算的操作:</p>
<pre class="brush: js">bCondition1 && bCondition2</pre>
<p>总是等于:</p>
<pre class="brush: js">!(!bCondition1 || !bCondition2)</pre>
<h4 id="将_OR_转换为_AND">将 OR 转换为 AND</h4>
<p>以下涉及<strong>布尔</strong>运算的操作:</p>
<pre class="brush: js">bCondition1 || bCondition2</pre>
<p>总是等于:</p>
<pre class="brush: js">!(!bCondition1 && !bCondition2)</pre>
<h3 id="删除嵌套的小括号">删除嵌套的小括号</h3>
<p>由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。</p>
<h4 id="删除嵌套的_AND">删除嵌套的 AND</h4>
<p>以下涉及<strong>布尔</strong>运算的操作:</p>
<pre class="brush: js">bCondition1 || (bCondition2 && bCondition3)</pre>
<p>总是等于:</p>
<pre class="brush: js">bCondition1 || bCondition2 && bCondition3</pre>
<h4 id="删除嵌套的_OR">删除嵌套的 OR</h4>
<p>以下涉及<strong>布尔</strong>运算的操作:</p>
<pre class="brush: js">bCondition1 && (bCondition2 || bCondition3)</pre>
<p>总是等于:</p>
<pre class="brush: js">!(!bCondition1 || !bCondition2 && !bCondition3)</pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">规范</th>
<th scope="col">状态</th>
<th scope="col">备注</th>
</tr>
<tr>
<td>{{SpecName('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Initial definition.</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-11.11')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.9">Logical NOT Operator</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.11">Binary Logical Operators</a></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-binary-logical-operators')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-logical-not-operator">Logical NOT Operator</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-binary-logical-operators">Binary Logical Operators</a></td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-binary-logical-operators')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td>Defined in several sections of the specification: <a href="http://tc39.github.io/ecma262/#sec-logical-not-operator">Logical NOT Operator</a>, <a href="http://tc39.github.io/ecma262/#sec-binary-logical-operators">Binary Logical Operators</a></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<p>{{Compat("javascript.operators.logical")}}</p>
<h2 id="参见">参见</h2>
<ul>
<li><a href="/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">按位操作符</a></li>
<li><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean">布尔值</a></li>
<li><a href="/zh-CN/docs/Glossary/Truthy">Truthy</a></li>
<li><a href="/zh-CN/docs/Glossary/Falsy">Falsy</a></li>
</ul>
|