Где бы я использовал побитовый оператор в JavaScript? - PullRequest
68 голосов
/ 17 марта 2009

Я прочитал 'что такое побитовые операторы?' , поэтому я знаю , что такое побитовые операторы , но я до сих пор не понимаю, как может использовать их. Кто-нибудь может предложить какие-нибудь реальные примеры того, где побитовый оператор был бы полезен в JavaScript?

Спасибо.

Edit:

Просто копаясь в jQuery-источнике Я нашел пару мест, где используются побитовые операторы, например: (только оператор &)

// Line 2756:
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

// Line 2101
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;

Ответы [ 16 ]

65 голосов
/ 17 марта 2009

Пример:

Анализирует шестнадцатеричное значение для получения значений цвета RGB.

var hex = 'ffaadd';
var rgb = parseInt(hex, 16); // rgb is 16755421


var red   = (rgb >> 16) & 0xFF; // returns 255
var green = (rgb >> 8) & 0xFF;  // 170
var blue  = rgb & 0xFF;     // 221  
42 голосов
/ 27 марта 2013

I интенсивно используют битовые операторы для числовых преобразований в производственных скриптах, потому что иногда они намного быстрее, чем их Math или parseInt эквиваленты.

Цена, которую я должен заплатить, читаемость кода . Поэтому я обычно использую Math в разработке и побитовом в производстве.

Некоторые трюки с производительностью можно найти на jsperf.com .

Как вы можете видеть, браузеры не оптимизируют Math.ceil и parseInt в течение многих лет, поэтому я предсказываю, что побитно будет более быстрый и короткий способ сделать вещи в будущем .

Дальнейшее чтение по SO ...


Бонус: шпаргалка для | 0: простой и быстрый способ конвертировать что-либо в целое число:

( 3|0 ) === 3;             // it does not change integers
( 3.3|0 ) === 3;           // it casts off the fractional part in fractionalal numbers
( 3.8|0 ) === 3;           // it does not round, but exactly casts off the fractional part
( -3.3|0 ) === -3;         // including negative fractional numbers
( -3.8|0 ) === -3;         // which have Math.floor(-3.3) == Math.floor(-3.8) == -4
( "3"|0 ) === 3;           // strings with numbers are typecast to integers
( "3.8"|0 ) === 3;         // during this the fractional part is cast off too
( "-3.8"|0 ) === -3;       // including negative fractional numbers
( NaN|0 ) === 0;           // NaN is typecast to 0
( Infinity|0 ) === 0;      // the typecast to 0 occurs with the Infinity
( -Infinity|0 ) === 0;     // and with -Infinity
( null|0 ) === 0;          // and with null,
( (void 0)|0 ) === 0;      // and with undefined
( []|0 ) === 0;            // and with an empty array
( [3]|0 ) === 3;           // but an array with one number is typecast to number
( [-3.8]|0 ) === -3;       // including the cast off of the fractional part
( [" -3.8 "]|0 ) === -3;   // including the typecast of strings to numbers
( [-3.8, 22]|0 ) === 0     // but an Array with several numbers is typecast to 0
( {}|0 ) === 0;                // an empty object is typecast to 0
( {'2':'3'}|0 ) === 0;         // or a not empty object
( (function(){})|0 ) === 0;    // an empty function is typecast to 0 too
( (function(){ return 3;})|0 ) === 0;

и немного магии для меня:

3 | '0px' === 3;
24 голосов
/ 08 февраля 2010

В JavaScript вы можете использовать двойное побитовое отрицание (~~n) в качестве замены для Math.floor(n) (если n - положительное число) или parseInt(n, 10) (даже если n - отрицательное). n|n и n&n всегда дают те же результаты, что и ~~n.

var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3

// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4

Одиночное побитовое отрицание (~) вычисляет -(parseInt(n, 10) + 1), поэтому два побитовых отрицания вернутся -(-(parseInt(n, 10) + 1) + 1).

Следует отметить, что из этих трех альтернатив n|n представляется наиболее быстрым .

Обновление: Более точные тесты здесь: http://jsperf.com/rounding-numbers-down

(Как опубликовано в Странный язык )

18 голосов
/ 27 февраля 2014

A реальная жизнь пример :

^ XOR по битам как I/O переключатель

Используется как value ^= 1 будет меняться при каждом вызове value на 0, 1, 0, 1 ...

function toggle(evt) {
  evt.target.IO ^= 1;                                    // Bitwise XOR as 1/0 toggler
  evt.target.textContent = evt.target.IO ? "ON" : "OFF"; // Unleash your ideas
}

document.querySelectorAll("button").forEach( el =>
  el.addEventListener("click", toggle)
);
<button>OFF</button>
<button>OFF</button>
<button>OFF</button>
16 голосов
/ 17 марта 2009

Учитывая достижения Javascript (особенно с nodejs, который позволяет программировать на стороне сервера с js), в JS появляется все более и более сложный код. Вот несколько случаев, когда я использовал побитовые операторы:

  • Операции с IP-адресом:

    //computes the broadcast address based on the mask and a host address
    broadcast = (ip & mask) | (mask ^ 0xFFFFFFFF)
    
    
    //converts a number to an ip adress 
    sprintf(ip, "%i.%i.%i.%i", ((ip_int >> 24) & 0x000000FF),
                             ((ip_int >> 16) & 0x000000FF),
                             ((ip_int >>  8) & 0x000000FF),
                             ( ip_int        & 0x000000FF));
    

Примечание: это код C, но JS почти идентичен

  • Алгоритмы CRC часто их используют

Проверьте запись в Википедии на этом

  • Операции с разрешением экрана
12 голосов
/ 27 июня 2014

Чтобы узнать, нечетное ли число:

function isOdd(number) {
    return !!(number & 1);
}

isOdd(1); // true, 1 is odd
isOdd(2); // false, 2 is not odd
isOdd(357); // true, 357 is odd

Быстрее, чем модуль - используйте там, где производительность действительно имеет значение!

11 голосов
/ 12 июня 2012

Несколько других примеров того, как использовать поразрядно не и не поразрядно дважды:

Работа на полу

~~2.5    // 2
~~2.1    // 2
~~(-2.5) // -2

Проверьте, вернул ли indexOf -1 или нет

var foo = 'abc';
!~foo.indexOf('bar'); // true
10 голосов
/ 17 марта 2009

Вы можете использовать их для переключения логического значения:

var foo = 1;
var bar = 0;
alert(foo ^= 1);
alert(bar ^= 1);

Это немного глупо, хотя по большей части побитовые операторы не имеют много приложений в Javascript.

6 голосов
/ 18 января 2016
var arr = ['abc', 'xyz']

раздражен писать

if (arr.indexOf('abc') > -1) {
  // 'abc' is in arr
}

if (arr.indexOf('def') === -1) {
  // 'def' is not in arr
}

проверить, находится ли что-то внутри массива?

Вы можете использовать побитовый оператор ~ примерно так:

if (~arr.indexOf('abc')) {
  // 'abc' is in arr
}

if (! ~arr.indexOf('def')) {
  // 'def' is not in arr
}
4 голосов
/ 17 марта 2009

битмаски .

Широко используется, например, в событиях JS.

...