написать впереди
Сегодня давайте узнаем о побитовых операторах в операторах JS.
В стандарте языка JS описан набор операторов, которые можно использовать для манипулирования значениями данных, включая математические операторы, битовые операторы, реляционные операторы, операторы равенства, логические операторы, условные операторы и операторы ES7, оператор экспоненты и т. д. , почему их называют операторами, ведь они все символы. . .
В этой группе операторов, по сравнению с часто используемыми нами операторами, такими как сложение, вычитание, умножение и деление, логическое суждение, равенство, логические операции и т. д., побитовый оператор кажется совершенно особым классом, потому что побитовый оператор не так интуитивно, многие только начинают и даже старые программисты не любят его использовать
Большинство людей думают, что использование слишком большого количества причудливых битовых операторов в процессе написания программ очень плохо сказывается на чтении.Хотя это может привести к некоторым улучшениям производительности по сравнению с проектом, необходимо выбрать опыт чтения и если вы иметь немного производительности, вы, скорее всего, выберете первое
Слова говорят,но это не причина,почему все не учат.Если битовую операцию знают все,то эти骚操作
Это стало рутинной операцией. Некоторые люди могут сказать, что даже если они понимают битовые операции, требуется время, чтобы подумать о чтении фрагмента кода, состоящего из битовых операторов. Но это нормально, если вы добавите эквивалентную аннотацию
Короче пользоваться им нельзя, но знать надо.Существование разумно, и любой спор не повод его не изучать
(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]]*~+[]]
Что ж, давайте начнем с этого кусочка чистого красного кода.
Прежде чем читать эту статью, пожалуйста, сначала прочитайте эту статью
Важное сказано три раза.Вышеприведенная статья предназначена для подготовки к этой статье.В статье рассказывается о некоторых вещах, связанных с цифровыми технологиями, двоичном преобразовании, исходном коде, обратном коде, дополнительном коде и цифровом хранилище в JS и т. д. После прочтения будет легко прочитать эту статью выше
Это также для вас, чтобы просмотреть некоторые основы компьютерного здравого смысла.По оценкам, все давно забыли эти основы на поле боя.В противном случае, это будет немного запутанно, чтобы напрямую жевать это.
битовая операция
Напомним, все мы знаем, что обычно используем десятичные значения для расчета0~9
, но компьютер это машина, он может распознавать только бинарные
Согласно международному стандарту IEEE 754,JavaScript
При хранении чисел они всегда сохраняются как числа с плавающей запятой двойной точности.В этом формате для хранения значений используется 64-битный двоичный код.64 бита — это 64 бита (бит), что эквивалентно 8 байтам, из которых от 0 до 51 хранится числа (фрагмент). ), от 52 до 62 хранят показатель степени, 63 бита хранят знак
В битовой операции JS для вычисления не используются 64 бита.Сначала значение преобразуется в 32-битное значение в фоновом режиме, а затем выполняется операция битовой операции.После завершения вычисления битовой операции 32-битная преобразуется в 64-битное хранилище.Весь процесс похож на работу с 32-битными значениями, поэтому, когда мы понимаем битовые операции, нам нужно обращать внимание только на эти 32-битные двоичные целые числа, потому что 64-битный формат хранения невидим, но это также из-за операции преобразования по умолчанию в фоновом режиме. Он имеет побочный эффект для языка JS, то есть специальные значения NaN и Infinity напрямую обрабатываются как 0 в побитовых операциях.
На самом деле это не только JS, но и битовые операции многих языков.
Подписанный и неподписанный
Вперемежку с небольшим знанием точки,ECMAScript
Существует два типа целых чисел: целые числа со знаком (допускаются как положительные, так и отрицательные числа) и целые числа без знака (допускаются только положительные числа).
В ECMAScript все целочисленные литералы по умолчанию являются целыми числами со знаком.
Целые числа со знаком, как упоминалось выше, первый бит в левой части двоичного файла — это знаковый бит, указывающий, является ли число положительным или отрицательным.
Беззнаковое целое не имеет бита знака.Без позиции знака это означает, что оно не может выражать отрицательные числа.В то же время, поскольку нет позиции знака, его диапазон хранения будет больше, чем у целых чисел со знаком.
Теперь мы говорим, что мы начали оператор сайта, вычисляя подписать бит разделены на семь, у нас есть одна дорога к
Побитовые не нет (~)
Кратко
Побитовый оператор НЕ можно также назвать побитовым отрицанием, он использует~
Представление символа, функция инвертирует бит, 1 становится 0, 0 становится 1
Друзья, прочитавшие вышеизложенное, могут обнаружить, что это, похоже, обратный код?
Да, мы можем прямо понять, что побитовое отрицание - это взять его двоичный инверсный код, но инверсный код означает, что знаковый бит остается неизменным, а остальные позиции инвертируются, а побитовое отрицание означает, что знаковый бит также инвертируется после инверсионного кода.
Например:
Возьмем для примера 8-битное (битное) цифровое хранилище.
Найдите побитовое НЕ десятичного числа 2, двоичное число десятичного числа 2 равно0000 0010
, то его дополнение равно0111 1101
, знаковый бит также инвертируется, он становится1111 1101
, конечно, вы также можете напрямую инвертировать каждый бит двоичного числа 2, результат1111 1101
Мы знаем, что бит знака равен 1 для представления отрицательного числа, а отрицательные числа хранятся в дополнении компьютера, поэтому мы используем дополнение1111 1101
Найдите исходный код, а затем преобразуйте его в десятичный.Чтобы найти исходный код для дополнительного кода, нужно использовать дополнительный код, чтобы снова найти дополнительный код, то есть сначала взять обратный код, а затем дополнить его 1. Процесс вычисляется самостоятельно, и получается двоичный исходный код отрицательного числа.1000 00 11
, который является десятичным-3
то же, что и выше
Побитовое NOT-Is-Decimal для десятичного числа 1-2
Побитовое не-или-десятичное число десятичной цифры 0-1
Все вышеперечисленное — положительные числа, давайте рассмотрим пример отрицательных чисел.
Поскольку десятичное число -1 является отрицательным числом, мы сказали выше, что двоичное хранение отрицательных чисел в компьютере является методом дополнения, поэтому нам нужно сначала найти дополнение -1. Исходный двоичный код -11000 0001
, а затем найти обратный исходному коду, то есть1111 1110
, а затем добавьте 1, чтобы найти дополнение, то есть1111 1111
, то мы получаем окончательную форму дополнения -1, хранящуюся в двоичном виде как1111 1111
, и, наконец, мы инвертируем каждый бит этого двоичного файла, чтобы получить0000 0000
, что является десятичным числом 0
Эх! Это кажется регулярным После того, как мы попытались несколько раз, мы обнаружили, что конечный результат побитового не всегда инвертирует исходное значение и вычитает один, как показано ниже.
let a = 1
console.log(~a == (-a) - 1) // true
// 得到
~x = (-x) - 1
Зная это, мы можем вычислить результат по этому правилу после встречи с побитовым не-оператором, что удобнее, чем преобразование в двоичное вычисление.
Потом кто-то еще сказал, что так как и(-x) - 1
согласуется, так зачем использовать побитовое НЕ?
Очень просто, есть две причины, во-первых, операция битовой операции выполняется на базовом представлении значения, а скорость высокая. Во-вторых, потому что он использует только 2 символа, что более удобно. . .
Используйте побитовое НЕ ~, чтобы определить, равно ли оно -1.
Частота использования побитового не в проекте по-прежнему достаточно высока
Я полагаю, что вы часто видите следующую надпись
let str = "abcdefg"
if(!~str.indexOf("n")){
console.log("字符串 str 中不存在字符 n")
}
// 等同于
if(str.indexOf("n") == "-1"){
console.log("字符串 str 中不存在字符 n")
}
Как показано выше, мы знаем, чтоindexOf
Метод возвращает -1, если одинаковое значение не найдено, пока~-1 == 0 == false
,так!~-1 == 1 == true
, Вообще говоря, мы используем метод побитового неписания для проверки -1 является наиболее часто используемым, а также его легче всего принять в битовой операции.Разве это не особенно просто и удобно?
Используйте побитовое НЕ ~ округление
Среди побитовых операций НЕ другой распространенной является двойное округление НЕ побитовых операций, как показано ниже.
~~3.14 == 3
Многие знают, что это можно округлить, но не осмеливаются использовать, потому что не знают почему, поэтому давайте объясним, почему это можно округлить
Как мы уже говорили выше, в битовой операции JS он не будет использовать 64 бита для вычисления, он сначала преобразует значение в 32-битное целое число в фоновом режиме, а затем выполняет битовую операцию. 32 бита будут преобразованы в 64-битное хранилище, весь процесс подобен работе с 32-битными значениями, поэтому, когда мы разбираемся с битовыми операциями, нам нужно обращать внимание только на эти 32-битные двоичные целые числа.
Здесь мы видим, что 32-битный整数
, битовая операция работает с целыми числами. Когда фон выполняет преобразование 64-битного в 32-битное, дробная часть будет игнорироваться, и будут затронуты только целые числа, целые числа и целые числа. Помните
~3.14 == ~3
~5.89 == ~5
Как показано выше, тогда мы следуем приведенной выше формуле
~x == (-x) - 1
~~x == -((-x) - 1) -1 == -(-x) + 1 -1 == x
Итак, двойное НЕ в побитовых операциях~~
можно округлить, это округление полностью игнорирует десятичную часть
Побитовое И (&)
Кратко
побитовый оператор И&
, он имеет два операнда. Фактически, это сравнение двоичных битов двух операндов. Когда соответствующие биты двух операндов равны 1, результат равен 1, в противном случае он равен 0, как показано ниже.
Например:
очень прошу25 & 3
, что является значением операции И для десятичного числа 25 и десятичного числа 3.
Мы можем найти двоичные числа 25 и 3 соответственно и сравнить их.
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
& = 0000 0000 0000 0000 0000 0000 0000 0001
Как показано выше, окончательный двоичный результат нашего сравнения0000 ... 0001
, что является десятичным числом 1
Используйте побитовое И & для проверки четности
Побитовое, и эта вещь обычно не используется слишком часто, я обычно использую ее только при оценке нечетных и четных чисел, как показано ниже:
偶数 & 1 // 0
奇数 & 1 // 1
Поскольку двоичное число десятичного числа 1 равно0000 ... 0001
, только последняя цифра равна 1, а остальные равны 0, поэтому любое число, сравниваемое с ним, равно 0, кроме последней цифры, тогда, когда последняя цифра числа равна 1, что является нечетным числом, тогда результат равен 1, это число Когда последний бит равен 0, что является четным числом, тогда результат равен 0, ведь в двоичном коде есть только 0 и 1
Используйте побитовое И &, чтобы проверить, является ли число степенью двойки
Чтобы определить, является ли число целой степенью 2, используйтеn & (n - 1)
let a = 20;
let b = 32;
a & (a - 1) // 16 a不是2的整数幂
b & (b - 1) // 0 b是2的整数幂
Как показано выше, применяя эту небольшую формулу, когда результат равен 0, значение представляет собой целую степень числа 2.
На самом деле принцип тоже очень прост.Во-первых, давайте посмотрим на двоичный код, соответствующий степени числа 2.
0000 0001 -> 1 // 2^0
0000 0010 -> 2 // 2^1
0000 0100 -> 4 // 2^2
0000 1000 -> 8 // 2^3
0001 0000 -> 16 // 2^4
Как и выше, в степени 2 есть только одна единица, за которой следует некоторый 0 в двоичном формате, поэтому, когда мы оцениваем, является ли число степенью двойки, используйтеn & (n-1)
, если вы являетесь степенью 2, двоичный код после вычитания 1 из n состоит в том, что исходная 1 становится 0, а все последующие 0 становятся 1. В это время при побитовом сравнении и сравнении с самим собой каждый бит отличается, поэтому каждый бит равен 0, то есть конечный результат равен 0
Как раз для 👉LeetCode 231 Вопросы
Побитовое ИЛИ (|)
Кратко
побитовое ИЛИ со знаком|
Чтобы указать, что у него также есть два операнда, побитовое ИЛИ также сравнивает каждый бит двоичного файла двух операндов, но пока есть 1 с обеих сторон побитового ИЛИ, результат равен 1, только если обе стороны равны 0 , результат только 0, следующим образом
Например:
очень прошу25 | 3
, то есть значение операции ИЛИ десятичного числа 25 и десятичного числа 3
Мы можем найти двоичные числа 25 и 3 соответственно и сравнить их.
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
| = 0000 0000 0000 0000 0000 0000 0001 1011
Как показано выше, окончательный двоичный результат нашего сравнения0000 ... 0001 1011
, что является десятичным числом 27
Используйте побитовое ИЛИ | округление
При округлении мы также можем использовать побитовое или округление
1.111 | 0 // 1
2.234 | 0 // 2
Как показано выше, вам нужно только выполнить побитовую операцию ИЛИ над десятичной дробью с 0.
Принцип также прост: битовая операция работает с целыми числами, что эквивалентно выполнению побитовой операции ИЛИ над целой частью значения и 0.
Двоичный код 0 — это все 0. При побитовом сравнении или 1 и 0 равны 1, а 0 и 0 равны 0. Полученный двоичный файл — это целая часть целочисленного значения, которое мы хотим получить.
Используйте побитовое ИЛИ | вместо Math.round()
Мы знаем, что немного выше или могут быть округлены, на самом деле, округление его так бывает, это положительное число плюс 0,5, отрицательный или минус 0,5 побитового для округления, правда в том, что простой, следующим образом
let a1 = 1.1
let a2 = 1.6
a1 + 0.5 | 0 // 1
a2 + 0.5 | 0 // 2
let b1 = -1.1
let b2 = -1.6
b1 - 0.5 | 0 // -1
b2 - 0.5 | 0 // -2
Нажмите или XOR (^)
Кратко
Побитовое исключающее ИЛИ с использованием символов^
Чтобы указать, что разница между побитовым XOR и побитовым ИЛИ заключается в том, что для сравнения побитовое XOR возвращает 1 только тогда, когда один бит равен 1, оба бита равны 1 или оба бита равны 0 и оба возвращают 0, следующим образом
Процесс операции XOR можно рассматривать как добавление двух чисел, а затем удаление переноса, 0 + 0 = 0, 1 + 0 = 1, 1 + 1 = 0, так будет легче запомнить
Например:
очень прошу25 ^ 3
, который является XOR десятичных чисел 25 и десятичных чисел 3
Мы можем найти двоичные числа 25 и 3 соответственно и сравнить их.
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
--------------------------------------------
| = 0000 0000 0000 0000 0000 0000 0001 1010
Как показано выше, окончательный двоичный результат нашего сравнения0000 ... 0001 1010
, что является десятичным числом 26
Используйте побитовое XOR ^, чтобы проверить, равны ли целые части
Побитовое исключающее ИЛИ можно использовать для определения равенства двух целых чисел следующим образом.
let a = 1
let b = 1
a ^ b // 0
1 ^ 1 // 0
2 ^ 2 // 0
3 ^ 3 // 0
Это связано с тем, что побитовое XOR возвращает 1 только тогда, когда один бит равен 1, и оба возвращают 0, когда оба бита равны 1 или оба равны 0. Два одинаковых числа идентичны в двоичном виде, поэтому оба равны 0.
Мы также можем использовать его, чтобы определить, равны ли целые части двух десятичных знаков, следующим образом
2.1 ^ 2.5 // 0
2.2 ^ 2.6 // 0
2.1 ^ 3.1 // 1
почему это? Помните, что битовые операции работают с целыми числами, целыми числами и целыми числами, а это означает, что приведенные выше сравнения можно понимать так же, как и следующие.
2 ^ 2 // 0
2 ^ 2 // 0
2 ^ 3 // 1
Обмен значениями осуществляется с помощью побитового XOR ^
Мы также можем использовать побитовое XOR, чтобы поменять местами значения двух переменных, следующим образом
let a = 1
let b = 2
a ^= b
b ^= a
a ^= b
console.log(a) // 2
console.log(b) // 1
Причина очень проста, мы должны сначала понять одну вещь
// 如果
a ^ b = c
// 那么
c ^ b = a
c ^ a = b
Теперь вы пересматриваете, почему обмен ценностями может быть обменен, присмотритесь повнимательнее.
Но здесь используйте^
Для обмена ценностями лучше использовать деструктуризацию ES6, потому что деструктуризация ES6 удобнее и понятнее.
Переключение между 0 и 1 с помощью побитового XOR ^
Переключение между 0 и 1, т. е. когда переменная равна 0, сделайте ее 1, а когда переменная равна 1, сделайте ее 0
обычно используетсяtoggle
Когда состояние переключателя переключается, когда состояние переключателя изменяется, обычные друзья будут делать следующее
let toggle = 0
if(toggle){
toggle = 0
}else{
toggle = 1
}
Более умные друзья будут использовать тернарный оператор
let toggle = 0
toggle = toggle ? 0 : 1
Использовать побитовое исключение или проще
let toggle = 0
toggle ^= 1
Принцип тоже простойtoggle ^= 1
Эквивалентноtoggle = toggle ^ 1
,мы знаем0 ^ 1
равно 1, и1 ^ 1
тогда 0
Используйте побитовое XOR ^, чтобы проверить, имеют ли два числа одинаковый знак
мы можем использовать(a ^ b) >= 0
Чтобы судить, имеют ли два числа один и тот же знак, то есть они оба положительные или отрицательные
let a = 1
let b = 2
let c = -2
(a ^ b) >= 0 // true
(a ^ c) >= 0 // false
Принцип тоже прост: левый первый бит положительного двоичного числа, то есть знаковый бит, равен 0, а отрицательное число — 1.
При сравнении побитового XOR только одно положительное и одно отрицательное значение равно 1, а результат равен 0, когда оба бита равны 0 или оба равны 1.
Следовательно, когда знаки двух значений совпадают, бит знака двоичного результата после побитового сравнения XOR должен быть равен 0, а конечное значение равно>=0
, наоборот<0
Сдвиг влево (
Кратко
символ сдвига влево<<
Представлять, как и его имя, то есть сдвигать двоичный код значения влево на заданное количество битов, знаковый бит остается неизменным
**Например: **
очень прошу2 << 5
, то есть операция сдвига десятичного числа 2 влево на 5 разрядов
Сначала мы преобразуем десятичное число 2 в двоичное, а затем сдвигаем влево на 5 бит, как показано ниже.
Мы получили новый бинарник, преобразованный в десятичный вид это значение 64
Сдвинув число x влево на y бит, мы можем фактически получить следующую формулу
x << y
// 等同于
x * 2^y
Используйте левый Shift
Используйте левый сдвиг, чтобы также округлить
1.111 << 0 // 1
2.344 << 0 // 2
Принцип заключается в том, что битовая операция работает с целыми числами, игнорируя дробную часть, которая эквивалентна целой части значения, и сдвигая влево на 0 бит, результатом остается целая часть
Сдвиг вправо со знаком (>>)
Кратко
Подписанный правый сдвиг со знаком>>
Для представления, то есть двоичный код значения сдвигается вправо на заданное число бит, а знаковый бит остается неизменным, что противоположно сдвигу влево
Например:
очень прошу64 >> 5
, то есть операция получения знакового сдвига вправо на 5 бит для десятичного числа 64
Сначала мы преобразуем десятичное число 64 в двоичное, а затем сдвигаем вправо 5 бит, как показано ниже.
Сдвиг вправо со знаком также создаст пробел после сдвига цифры.Пробел расположен слева от числа, но после знакового бита,ECMAScript
заполнить эти вакансии значением знакового бита
Затем мы получаем новый двоичный код, который представляет собой значение 2 при преобразовании в десятичное число, что на самом деле является обратной операцией сдвига влево.
Точно так же, сдвинув число x вправо на y бит, мы также можем получить следующую формулу
x >> y
// 等同于
x / 2^y
Используйте правый сдвиг >> раунд
Используйте правый сдвиг, а также левый сдвиг для округления
1.111 >> 0 // 1
2.344 >> 0 // 2
Принцип тот же.Битовая операция работает с целыми числами, игнорируя дробную часть, которая эквивалентна целой части значения.Сдвиньте вправо на 0 бит, и результатом будет целая часть.
Беззнаковый сдвиг вправо (>>>)
Кратко
Использование сдвига вправо без знака>>>
Указывает, что отличие от сдвига вправо со знаком состоит в том, что он на три знака больше, чем сдвигает все 32-битные символы значения вправо.
Для положительных чисел сдвиг вправо без знака заполнит пустые биты 0, независимо от того, какой бит знака, так что результаты сдвига вправо со знаком и сдвига вправо без знака положительных чисел будут одинаковыми.
С отрицательными числами дело обстоит иначе: когда отрицательное число сдвинуто вправо без знака, то есть двоичный код отрицательного числа, включая знак, сдвигается вправо, биты, сдвинутые вправо, отбрасываются, а левые сторона заполняется 0. Поскольку бит знака меняется на 0, результат всегда неотрицательный
Затем кто-то может спросить, если отрицательное число без знака сдвинуто вправо на 0 бит, мы можем это проверить.
Сделать десятичный -1 беззнаковый сдвиг вправо 0 бит
-1 - это отрицательное число, а двоичное хранилище в памяти - это дополнение до двух, т.е.1111 .... 1111 1111
, 32 бита это все 1, пишем в программе-1 >>> 0
запустить, чтобы получить десятичные числа4294967295
, а затем используйте инструмент преобразования двоичных файлов, чтобы преобразовать его в двоичный файл, чтобы получить 32-разрядный двоичный файл.1111 .... 1111 1111
, так что даже если беззнаковый сдвиг вправо на 0 бит, результат все равно будет большим положительным числом
Использовать сдвиг вправо без знака >>> раунд (положительное число)
Сдвиг вправо без знака похож на сдвиг вправо и влево со знаком. Сдвиг 0 битов можно округлить, но сдвиг вправо без знака может поддерживать только округление положительных чисел. Что касается принципа, я говорил это бесчисленное количество раз, я думаю, вы уже вспомнил вживую, вот так
1.323 >>> 0 // 1
2.324 >>> 0 // 2
Управление разрешениями с помощью побитовых операций
В дополнение к сценариям использования каждой битовой операции выше, есть еще немного более сложный сценарий, где несколько битовых операторов используются в комбинации, то есть управление разрешениями.Я не собирался это писать, но по просьбе многих мелкие партнеры, добавленные в
В нашем известном источнике Vue, чтобы выполнить аутентификацию с помощью битовой операции, мы используем Vue для этой части в качестве примера, чтобы объяснить источник
В исходный код Vue,patchFlagsфайлVisualDOM
средняя параvnode
Тег типа, роль заключается в обновленииDOM树
будет основываться наvnode
тип для использования разных стратегий обновления (это не важно понимать), давайте посмотрим на определение типа здесь
// Patch flags can be combined using the | bitwise operator and can be checked
// using the & operator, e.g.
//
// const flag = TEXT | CLASS
// if (flag & TEXT) { ... }
//
// Check the `patchElement` function in './renderer.ts' to see how the
// flags are handled during diff.
export const enum PatchFlags {
TEXT = 1, // 1 << 0
CLASS = 1 << 1,
STYLE = 1 << 2,
PROPS = 1 << 3,
FULL_PROPS = 1 << 4,
HYDRATE_EVENTS = 1 << 5,
STABLE_FRAGMENT = 1 << 6,
KEYED_FRAGMENT = 1 << 7,
UNKEYED_FRAGMENT = 1 << 8,
NEED_PATCH = 1 << 9,
DYNAMIC_SLOTS = 1 << 10,
// SPECIAL FLAGS -------------------------------------------------------------
// Special flags are negative integers. They are never matched against using
// bitwise operators (bitwise matching should only happen in branches where
// patchFlag > 0), and are mutually exclusive. When checking for a special
// flag, simply check patchFlag === FLAG.
HOISTED = -1,
BAIL = -2
}
Выше мы видим, чтоPatchFlags
определено вTEXT、CLASS
Всего существует 11 типов, за исключением последних двух специальных типов, значение каждого типа получается сдвигом 1 влево на один разряд по очереди
На самом деле, в комментариях в начале документа автор дал использование очень интимно, некоторые студенты могут не любить его читать или плохо понимать английский язык.
Проще говоря, следующие типы, которые мы можем использовать|
Чтобы предоставить разрешения типа комбинации, используйте&
выполнить проверку разрешения типа
Давайте начнем снова
Сдвиг влево (
Во-первых, используйте сдвиг влево на 1 для назначения различных типов разрешений.Как мы сказали выше, операция сдвига влево заключается в перемещении двоичного кода числового значения влево в соответствии с указанным количеством цифр, а бит знака остается без изменений, то вот так
// 1 的二进制为 00000001
1 << 0 // 00000001
1 << 1 // 00000010
1 << 2 // 00000100
1 << 3 // 00001000
1 << 4 // 00010000
1 << 5 // 00100000
...
Как показано выше, все типы разрешений уникальны и соответствуют требованиям назначения разрешений.Кроме того, только 1 цифра равна 1 в двоичном коде после сдвига влево выше, вы нашли это😄
Побитовое И (&) проверить разрешения
Затем мы смотрим на проверку разрешения типа, мы сначала инициализируем несколько разных ролей разрешения пользователя.
let permission1 = 0 // 无任何权限
let permission2 = TEXT // 1 >> 0
let permission3 = CLASS // 1 >> 1
Если наше условие состоит в том, чтобы определить, имеет ли роль пользователяCLASS
Разрешение, то есть о нем можно судить по побитовому И (&)
if(permission1 & CLASS) // 00000000 & 00000010 = 00000000 = 0 = false
if(permission2 & CLASS) // 00000001 & 00000010 = 00000000 = 0 = false
if(permission3 & CLASS) // 00000010 & 00000010 = 00000010 = 2 = true
Зачем? Поскольку мы сказали выше, & предназначено для сравнения двоичных битов двух операндов.Когда соответствующие биты двух операндов равны 1, результат равен 1, в противном случае он равен 0.
Побитовое ИЛИ (|) для предоставления разрешений
Далее рассмотрим предоставление разрешений и разрешения комбинированного типа.
мы хотим одинTEXT
а такжеCLASS
Комбинированная роль разрешений Vue, как указано в комментариях к исходному коду Vue, использует|
, то есть побитовое ИЛИ
Побитовое ИЛИ Как мы уже говорили выше, это сравнение каждого бита двоичного файла.Пока есть одна 1 с обеих сторон, результат равен 1. Только когда обе стороны равны 0, результат равен 0
// 初始化一个新的用户角色 permission4 并初始化,初始化角色即无权限状态 0
let permission4 = 0
// 赋予 TEXT(1 >> 0) 权限
permission4 |= TEXT
// 赋予 CLASS(1 << 1) 权限
permission4 |= CLASS
// 新的组合类型的用户角色权限即 00000011 ,如下
permission4 = 0 | TEXT | CLASS
// 0 = 0000 0000
// TEXT = 0000 0001
// CLASS = 0000 0010
// -----------------------
// permission4 = 0000 0011
// 权限校验,& 对比二进制操作位
permission4 & TEXT // 0000 0011 & 0000 0001 = 0000 0001 = 1 = true
permission4 & CLASS // 0000 0011 & 0000 0010 = 0000 0010 = 2 = true
permission4 & STYLE // 0000 0011 & 0000 0100 = 0000 0000 = 0 = false
В этот момент мы можем использовать<<
,|
,&
Приходите и наслаждайтесь управлением разрешениями, выget
Достиг?
наконец
Фактически, текущие базовые сценарии использования битовых операций широко не используются.В основном, большинство людей используют его, как указано выше, например, управление разрешениями, округление, оценка четности, оценка -1, переключение 0/1 и т. д. После прочтения статью терпеливо, вы обнаружите, что принцип на самом деле очень прост, вот и все, нет необходимости кричать и убивать весь день, это все еще одно и то же предложение, используете вы его или нет, зависит от вас, но это не причина почему ты не будешь
На этом все заканчивается, не скупитесь на лайки, если есть ошибки в статье, указывайте на них и продвигайтесь вперед вместе, также приглашаем обратить внимание на паблик "Нерегулярный фронтенд"