aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html
blob: 63e6b408a09ecc4afa088ba5c154976b4aa8207d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
---
title: 按位操作符
slug: >-
  conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560
tags:
  - js ^ & Bitwise Operators
translation_of: Web/JavaScript/Reference/Operators
translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators
original_slug: Web/JavaScript/Reference/Operators/Bitwise_Operators
---
<div>{{jsSidebar("Operators")}}</div>

<h2 id="Summary" name="Summary">概述</h2>

<p><strong>按位操作符(Bitwise operators)</strong> 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制<a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">数值</a>。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。</p>

<p>下面的表格总结了JavaScript中的按位操作符:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <th>运算符</th>
   <th>用法</th>
   <th>描述</th>
  </tr>
  <tr>
   <td><a href="#Bitwise_AND">按位与( AND)</a></td>
   <td style="white-space: nowrap;"><code>a &amp; b</code></td>
   <td>对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_OR">按位或(OR)</a></td>
   <td style="white-space: nowrap;"><code>a | b</code></td>
   <td>对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_XOR">按位异或(XOR)</a></td>
   <td style="white-space: nowrap;"><code>a ^ b</code></td>
   <td>对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_NOT">按位非(NOT)</a></td>
   <td style="white-space: nowrap;"><code>~ a</code></td>
   <td>反转操作数的比特位,即0变成1,1变成0。</td>
  </tr>
  <tr>
   <td><a href="#Left_shift">左移(L</a><a href="#Left_shift" style="line-height: 1.5;">eft shift)</a></td>
   <td style="white-space: nowrap;"><code>a &lt;&lt; b</code></td>
   <td>将 <code>a</code> 的二进制形式向左移 <code>b</code> (&lt; 32) 比特位,右边用0填充。</td>
  </tr>
  <tr>
   <td><a href="#Right_shift">有符号右移</a></td>
   <td style="white-space: nowrap;"><code>a &gt;&gt; b</code></td>
   <td>将 a 的二进制表示向右移<code> b </code>(&lt; 32) 位,丢弃被移出的位。</td>
  </tr>
  <tr>
   <td><a href="#Unsigned_right_shift">无符号右移</a></td>
   <td style="white-space: nowrap;"><code>a &gt;&gt;&gt; b</code></td>
   <td>将 a 的二进制表示向右移<code> b </code>(&lt; 32) 位,丢弃被移出的位,并使用 0 在左侧填充。</td>
  </tr>
 </tbody>
</table>

<h2 id="有符号32位整数">有符号32位整数</h2>

<p>所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:</p>

<pre>00000000000000000000000100111010
</pre>

<p>下面编码 <code>~314</code>,即 <code>314</code> 的反码:</p>

<pre>11111111111111111111111011000101
</pre>

<p>最后,下面编码 <code>-314</code>,即 <code>314</code> 的反码再加1:</p>

<pre>11111111111111111111111011000110
</pre>

<p>补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(<em>sign bit</em>)。</p>

<p><code>0</code> 是所有比特数字0组成的整数。</p>

<pre>0 (base 10) = 00000000000000000000000000000000 (base 2)
</pre>

<p><code>-1</code> 是所有比特数字1组成的整数。</p>

<pre>-1 (base 10) = 11111111111111111111111111111111 (base 2)
</pre>

<p><code>-2147483648</code>(十六进制形式:<code>-0x80000000</code>)是除了最左边为1外,其他比特位都为0的整数。</p>

<pre>-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
</pre>

<p><code>2147483647</code>(十六进制形式:<code>0x7fffffff</code>)是除了最左边为0外,其他比特位都为1的整数。</p>

<pre>2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
</pre>

<p>数字<code>-2147483648</code><code>2147483647</code> 是32位有符号数字所能表示的最小和最大整数。</p>

<h2 id="按位逻辑操作符">按位逻辑操作符</h2>

<p>从概念上讲,按位逻辑操作符按遵守下面规则:</p>

<ul>
 <li>操作数被转换成32位整数,用比特序列(0和1组成)表示。超过32位的数字会被丢弃。<br>
  例如, 以下具有32位以上的整数将转换为32位整数:</li>
 <li>
  <pre>转换前: 11100110111110100000000000000110000000000001
转换后:             10100000000000000110000000000001</pre>
 </li>
 <li>第一个操作数的每个比特位与第二个操作数的相应比特位匹配:第一位对应第一位,第二位对应第二位,以此类推。</li>
 <li>位运算符应用到每对比特位,结果是新的比特值。</li>
</ul>

<h3 id="(按位与)"><a name="Bitwise_AND">&amp; (按位与)</a></h3>

<p>对每对比特位执行<strong>与(AND)操作</strong>。只有 a 和 b 都是 1 时,a AND b 才是 1。<strong>与操作</strong>的真值表如下:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <td class="header">a</td>
   <td class="header">b</td>
   <td class="header">a AND b</td>
  </tr>
  <tr>
   <td>0</td>
   <td>0</td>
   <td>0</td>
  </tr>
  <tr>
   <td>0</td>
   <td>1</td>
   <td>0</td>
  </tr>
  <tr>
   <td>1</td>
   <td>0</td>
   <td>0</td>
  </tr>
  <tr>
   <td>1</td>
   <td>1</td>
   <td>1</td>
  </tr>
 </tbody>
</table>

<pre>     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 &amp; 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
</pre>

<p>将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。</p>

<h3 id="(按位或)"><a name="Bitwise_OR">| (按位或)</a></h3>

<p>对每一对比特位执行<strong>或(OR)操作</strong>。如果 a 或 b 为 1,则 <code>a</code> OR <code>b</code> 结果为 1。<strong>或操作</strong>的真值表:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <td class="header">a</td>
   <td class="header">b</td>
   <td class="header">a OR b</td>
  </tr>
  <tr>
   <td>0</td>
   <td>0</td>
   <td>0</td>
  </tr>
  <tr>
   <td>0</td>
   <td>1</td>
   <td>1</td>
  </tr>
  <tr>
   <td>1</td>
   <td>0</td>
   <td>1</td>
  </tr>
  <tr>
   <td>1</td>
   <td>1</td>
   <td>1</td>
  </tr>
 </tbody>
</table>

<pre>     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
</pre>

<p>将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。</p>

<p>补充一些例子:</p>

<pre class="brush: js">1 | 0 ;                       // 1

1.1 | 0 ;                     // 1

'asfdasfda' | 0 ;             // 0

0 | 0 ;                       // 0

(-1) | 0 ;                    // -1

(-1.5646) | 0 ;               // -1

[] | 0 ;                      // 0

({}) | 0 ;                    // 0

"123456" | 0 ;            // 123456

1.23E2 | 0;               // 123

1.23E12 | 0;              // 1639353344

-1.23E2 | 0;              // -123

-1.23E12 | 0;             // -1639353344</pre>

<h3 id="(按位异或)"><a name="Bitwise_XOR">^ (按位异或)</a></h3>

<p>对每一对比特位执行<strong>异或(XOR)操作</strong>。当 a 和 b 不相同时,<code>a</code> XOR <code>b</code> 的结果为 1。<strong>异或操作</strong>真值表:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <td class="header">a</td>
   <td class="header">b</td>
   <td class="header">a XOR b</td>
  </tr>
  <tr>
   <td>0</td>
   <td>0</td>
   <td>0</td>
  </tr>
  <tr>
   <td>0</td>
   <td>1</td>
   <td>1</td>
  </tr>
  <tr>
   <td>1</td>
   <td>0</td>
   <td>1</td>
  </tr>
  <tr>
   <td>1</td>
   <td>1</td>
   <td>0</td>
  </tr>
 </tbody>
</table>

<pre>     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
</pre>

<p>将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。</p>

<h3 id="(按位非)"><a name="Bitwise_NOT">~ (按位非)</a></h3>

<p>对每一个比特位执行<strong>非(NOT)操作</strong>。NOT <code>a</code> 结果为 a 的反转(即反码)。<strong>非操作</strong>的真值表:</p>

<table class="standard-table">
 <tbody>
  <tr>
   <td class="header">a</td>
   <td class="header">NOT a</td>
  </tr>
  <tr>
   <td>0</td>
   <td>1</td>
  </tr>
  <tr>
   <td>1</td>
   <td>0</td>
  </tr>
 </tbody>
</table>

<pre> 9 (base 10) = 00000000000000000000000000001001 (base 2)
               --------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
</pre>

<p>对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。</p>

<p>与 indexOf 一起使用示例:</p>

<pre class="brush: js">var str = 'rawr';
var searchFor = 'a';

// 这是 if (-1*str.indexOf('a') &lt;= 0) 条件判断的另一种方法
if (~str.indexOf(searchFor)) {
  // searchFor 包含在字符串中
} else {
  // searchFor 不包含在字符串中
}

// (~str.indexOf(searchFor))的返回值
// r == -1
// a == -2
// w == -3
</pre>

<h2 id="按位移动操作符">按位移动操作符</h2>

<p>按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。</p>

<p>按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。</p>

<pre>注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,
又称为"高位编址"。
Big-Endian是最直观的字节序:
①把内存地址从左到右按照由低到高的顺序写出;
②把值按照通常的高位到低位的顺序写出;
③两者对照,一个字节一个字节的填充进去。</pre>

<h3 id="&lt;&lt;_(左移)"><a name="Left_shift">&lt;&lt; (左移)</a></h3>

<p>该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。</p>

<p>For example, <code>9 &lt;&lt; 2</code> yields 36:</p>

<pre>     9 (base 10): 00000000000000000000000000001001 (base 2)
                  --------------------------------
9 &lt;&lt; 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
</pre>

<p>在数字 <strong>x</strong> 上左移 <strong>y</strong> 比特得到 <strong>x * 2<sup>y</sup></strong>.</p>

<h3 id=">>_(有符号右移)"><a name="Right_shift">&gt;&gt; (有符号右移)</a></h3>

<p>该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。</p>

<p>例如, <code>9 &gt;&gt; 2</code> 得到 2:</p>

<pre>     9 (base 10): 00000000000000000000000000001001 (base 2)
                  --------------------------------
9 &gt;&gt; 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
</pre>

<p>相比之下, <code>-9 &gt;&gt; 2</code> 得到 -3,因为符号被保留了。</p>

<pre>     -9 (base 10): 11111111111111111111111111110111 (base 2)
                   --------------------------------
-9 &gt;&gt; 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
</pre>

<h3 id=">>>_(无符号右移)"><a name="Unsigned_right_shift">&gt;&gt;&gt; (无符号右移)</a></h3>

<p>该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)</p>

<p>对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 <code>9 &gt;&gt;&gt; 2</code><code>9 &gt;&gt; 2</code> 一样返回 2:</p>

<pre>      9 (base 10): 00000000000000000000000000001001 (base 2)
                   --------------------------------
9 &gt;&gt;&gt; 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
</pre>

<p>但是对于负数却不尽相同。 <code>-9 &gt;&gt;&gt; 2</code> 产生 1073741821 这和 <code>-9 &gt;&gt; 2</code> 不同:</p>

<pre>      -9 (base 10): 11111111111111111111111111110111 (base 2)
                    --------------------------------
-9 &gt;&gt;&gt; 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
</pre>

<h2 id="示例">示例</h2>

<h3 id="例子:标志位与掩码">例子:标志位与掩码</h3>

<p>位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。</p>

<p>例如,有 4 个标志位:</p>

<ul>
 <li>标志位 A:我们有 ant</li>
 <li>标志位 B:我们有 bat</li>
 <li>标志位 C:我们有 cat</li>
 <li>标志位 D:我们有 duck</li>
</ul>

<p>标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 <code>flags</code> 的二进制值为 0101:</p>

<pre class="brush: js">var flags = 5;   // 二进制 0101
</pre>

<p>这个值表示:</p>

<ul>
 <li>标志位 A 是 true (我们有 ant);</li>
 <li>标志位 B 是 false (我们没有 bat);</li>
 <li>标志位 C 是 true (我们有 cat);</li>
 <li>标志位 D 是 false (我们没有 duck);</li>
</ul>

<p>因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。</p>

<p>掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:</p>

<pre class="brush: js">var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000
</pre>

<p>新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:</p>

<pre class="brush: js">var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 =&gt; 1011
</pre>

<p>某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:</p>

<pre class="brush: js">// 如果我们有 cat
if (flags &amp; FLAG_C) { // 0101 &amp; 0100 =&gt; 0100 =&gt; true
   // do stuff
}
</pre>

<p>一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:</p>

<pre class="brush: js">// 如果我们有 bat 或者 cat 至少一个
// (0101 &amp; 0010) || (0101 &amp; 0100) =&gt; 0000 || 0100 =&gt; true
if ((flags &amp; FLAG_B) || (flags &amp; FLAG_C)) {
   // do stuff
}
</pre>

<pre class="brush: js">// 如果我们有 bat 或者 cat 至少一个
var mask = FLAG_B | FLAG_C; // 0010 | 0100 =&gt; 0110
if (flags &amp; mask) { // 0101 &amp; 0110 =&gt; 0100 =&gt; true
   // do stuff
}
</pre>

<p>可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:</p>

<pre class="brush: js">// 我们有 cat 和 duck
var mask = FLAG_C | FLAG_D; // 0100 | 1000 =&gt; 1100
flags |= mask;   // 0101 | 1100 =&gt; 1101
</pre>

<p>可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :</p>

<pre class="brush: js">// 我们没有 ant 也没有 cat
var mask = ~(FLAG_A | FLAG_C); // ~0101 =&gt; 1010
flags &amp;= mask;   // 1101 &amp; 1010 =&gt; 1000
</pre>

<p>如上的掩码同样可以通过 <code>~FLAG_A &amp; ~FLAG_C</code> 得到(德摩根定律):</p>

<pre class="brush: js">// 我们没有 ant 也没有 cat
var mask = ~FLAG_A &amp; ~FLAG_C;
flags &amp;= mask;   // 1101 &amp; 1010 =&gt; 1000
</pre>

<p>标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:</p>

<pre class="brush: js">// 如果我们以前没有 bat ,那么我们现在有 bat
// 但是如果我们已经有了一个,那么现在没有了
// 对 cat 也是相同的情况
var mask = FLAG_B | FLAG_C;
flags = flags ^ mask;   // 1100 ^ 0110 =&gt; 1010
</pre>

<p>最后,所有标志位可以通过非运算翻转:</p>

<pre class="brush: js">// entering parallel universe...
flags = ~flags;    // ~1010 =&gt; 0101
</pre>

<h3 id="转换片段">转换片段</h3>

<p>将一个二进制数的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code> 转换为十进制的 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code>:</p>

<pre class="brush: js">var sBinString = "1011";
var nMyNumber = parseInt(sBinString, 2);
alert(nMyNumber); // 打印 11
</pre>

<p>将一个十进制的 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code> 转换为二进制数的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code>:</p>

<pre class="brush: js">var nMyNumber = 11;
var sBinString = nMyNumber.toString(2);
alert(sBinString); // 打印 1011
</pre>

<h3 id="自动化掩码创建">自动化掩码创建</h3>

<p>如果你需要从一系列的 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Boolean</a></code> 值创建一个掩码,你可以:</p>

<pre class="brush: js">function createMask () {
  var nMask = 0, nFlag = 0, nLen = arguments.length &gt; 32 ? 32 : arguments.length;
  for (nFlag; nFlag &lt; nLen; nMask |= arguments[nFlag] &lt;&lt; nFlag++);
  return nMask;
}
var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
var mask2 = createMask(false, false, true); // 4, i.e.: 0100
var mask3 = createMask(true); // 1, i.e.: 0001
// etc.

alert(mask1); // 打印 11
</pre>

<h3 id="逆算法:从掩码得到布尔数组">逆算法:从掩码得到布尔数组</h3>

<p>如果你希望从掩码得到得到 <code><a href="/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Boolean</a></code> <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Array" title="/en-US/docs/JavaScript/Reference/Global_Objects/Array">Array</a></code></p>

<pre class="brush: js">function arrayFromMask (nMask) {
  // nMask 必须介于 -2147483648 和 2147483647 之间
  if (nMask &gt; 0x7fffffff || nMask &lt; -0x80000000) {
    throw new TypeError("arrayFromMask - out of range");
  }
  for (var nShifted = nMask, aFromMask = []; nShifted;
       aFromMask.push(Boolean(nShifted &amp; 1)), nShifted &gt;&gt;&gt;= 1);
  return aFromMask;
}

var array1 = arrayFromMask(11);
var array2 = arrayFromMask(4);
var array3 = arrayFromMask(1);

alert("[" + array1.join(", ") + "]");
// 打印 "[true, true, false, true]", i.e.: 11, i.e.: 1011
</pre>

<p>你可以同时测试以上两个算法……</p>

<pre class="brush: js">var nTest = 19; // our custom mask
var nResult = createMask.apply(this, arrayFromMask(nTest));

alert(nResult); // 19
</pre>

<p>仅仅由于教学目的 (因为有 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString">Number.toString(2)</a></code> 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:</p>

<pre class="brush: js">function createBinaryString (nMask) {
  // nMask must be between -2147483648 and 2147483647
  for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag &lt; 32;
       nFlag++, sMask += String(nShifted &gt;&gt;&gt; 31), nShifted &lt;&lt;= 1);
  return sMask;
}

var string1 = createBinaryString(11);
var string2 = createBinaryString(4);
var string3 = createBinaryString(1);

alert(string1);
// 打印 00000000000000000000000000001011, i.e. 11
</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>ECMAScript 1st Edition.</td>
   <td>Standard</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}<br>
    {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}<br>
    {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}<br>
    {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}<br>
    {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<p>{{ CompatibilityTable() }}</p>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td><a href="#Bitwise_NOT">Bitwise NOT (<code>~</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_AND">Bitwise AND (<code>&amp;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_OR">Bitwise OR (<code>|</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_XOR">Bitwise XOR (<code>^</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Left_shift">Left shift (<code>&lt;&lt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Right_shift">Right shift (<code>&gt;&gt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Unsigned_right_shift">Unsigned right shift (<code>&gt;&gt;&gt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
  </tr>
  <tr>
   <td><a href="#Bitwise_NOT">Bitwise NOT (<code>~</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_AND">Bitwise AND (<code>&amp;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_OR">Bitwise OR (<code>|</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Bitwise_XOR">Bitwise XOR (<code>^</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Left_shift">Left shift (<code>&lt;&lt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Right_shift">Right shift (<code>&gt;&gt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
  <tr>
   <td><a href="#Unsigned_right_shift">Unsigned right shift (<code>&gt;&gt;&gt;</code>)</a></td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
   <td>{{ CompatVersionUnknown() }}</td>
  </tr>
 </tbody>
</table>
</div>

<h2 id="See_also" name="See_also">相关链接</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">Logical operators</a></li>
 <li>
  <p><strong>js ^</strong> &amp; <strong>Bitwise Operators</strong></p>
 </li>
</ul>