国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【譯】 JavaScript中按位操作符的有趣應(yīng)用

oneasp / 2535人閱讀

摘要:檢查設(shè)定位操作符還有一些其他有用的位屏蔽應(yīng)用。請注意,位掩碼中的位將有效地關(guān)閉十進制數(shù)中的相應(yīng)位,因為。

原文標(biāo)題:Interesting use cases for JavaScript bitwise operators

原文地址:https://blog.logrocket.com/in...

本文首發(fā)于公眾號:符合預(yù)期的CoyPan

JavaScript提供了幾種運算符,可以對一些簡單的值進行基本操作,比如算術(shù)操作、賦值操作、邏輯操作、按位操作等。

我們經(jīng)常可以看到混合了賦值操作,算術(shù)操作和邏輯操作的JavaScript代碼。但是,按位操作的代碼就不是那么常見了。

JavaScript的按位操作符

~按位非

&按位與

|按位或

^按位異或

<<左移

>>有符號右移

>>>無符號右移

在本文中,我們將過一遍所有的按位操作符并且試著理解他們是怎么工作的。同時,我們會編寫簡單的JavaScript的代碼,來看一看一些有趣的按位操作符運用。這需要我們了解一下javascript位操作符如何將其操作數(shù)表示為有符號的32位整數(shù)。讓我們開始吧。

按位非(~)

~運算符是一元運算符;因此,它只需要一個操作數(shù)。~運算符對其操作數(shù)的每一位執(zhí)行NOT操作。非運算的結(jié)果稱為補碼。整數(shù)的補碼是通過將整數(shù)的每一位倒轉(zhuǎn)而形成的。

對于給定的整數(shù)(例如170),可以使用~運算符計算補碼,如下所示:

// 170 => 00000000000000000000000010101010
// --------------------------------------
//  ~ 00000000000000000000000010101010
// --------------------------------------
//  = 11111111111111111111111101010101
// --------------------------------------
//  = -171 (decimal)

console.log(~170); // -171

javascript按位運算符將其操作數(shù)轉(zhuǎn)換為二進制補碼格式的32位有符號整數(shù)。因此,當(dāng)對整數(shù)使用~運算符時,得到的值是整數(shù)的補碼。整數(shù)A的補碼的結(jié)果為 - (A+1) 。

~170 => -(170 + 1) => -171

下面是一些需要注意的關(guān)于32位有符號整數(shù)的要點,這些整數(shù)由javascript位運算符使用:

最有意義(最左邊)的位稱為符號位。正整數(shù)的符號位總是0,負(fù)整數(shù)的符號位總是1。

除符號位之外的其余31位用于表示整數(shù)。因此,可以表示的最大32位整數(shù)是(2^32-1),它是2147483647,而最小整數(shù)是(2^31),它是-2147483648。

對于不在32位有符號整數(shù)范圍內(nèi)的整數(shù),最有效位將被丟棄,直到整數(shù)在該范圍內(nèi)。

以下是一些重要數(shù)字的32位序列表示:

0 => 00000000000000000000000000000000
-1 => 11111111111111111111111111111111
2147483647 => 01111111111111111111111111111111
-2147483648 => 10000000000000000000000000000000

從上面的描述可以很容易得出:

                  ~0 => -1
         ~-1 => 0
 ~2147483647 => -2147483648
~-2147483648 => 2147483647
找到索引

大多數(shù)JavaScript內(nèi)置對象(如數(shù)組和字符串)都有一些有用的方法,可用于檢查數(shù)組中是否存在項或字符串中是否存在子字符串。以下是一些方法:

Array.indexOf()

Array.lastIndexOf()

Array.findIndex()

String.indexOf()

String.lastIndexOf()

String.search()

這些方法都返回某一項或子字符串的從零開始的索引(如果找到);否則,它們返回-1。例如:

const numbers = [1, 3, 5, 7, 9];

console.log(numbers.indexOf(5)); // 2
console.log(numbers.indexOf(8)); // -1

如果我們對么某一項或者子字符串的索引位置不感興趣,我們可以選擇使用布爾值。當(dāng)未找到的項或者子字符串時,返回-1,我們可以認(rèn)為是false,返回其他的值都是true。

function foundIndex (index) {
  return Boolean(~index);
}

在上面的代碼片段中,~運算符在-1上使用時的值為0。使用boolean()將值強制轉(zhuǎn)換為boolean,返回false。對于其他每個索引值,返回true。因此,以前的代碼段可以修改如下:

const numbers = [1, 3, 5, 7, 9];

console.log(foundIndex(numbers.indexOf(5))); // true
console.log(foundIndex(numbers.indexOf(8))); // false
按位與(&)

& 操作符對其操作數(shù)的每一對對應(yīng)位執(zhí)行一個和運算。& 操作符僅當(dāng)兩個位都為1時返回1;否則返回0。因此,與運算的結(jié)果等于將每一對對應(yīng)的位相乘。

下面是與操作的可能值:

(0 & 0) === 0     // 0 x 0 = 0
(0 & 1) === 0     // 0 x 1 = 0
(1 & 0) === 0     // 1 x 0 = 0
(1 & 1) === 1     // 1 x 1 = 1
"關(guān)閉"某些位

&操作符通常用于位屏蔽應(yīng)用,以確保為給定的位序列關(guān)閉某些位。這是基于這樣一個事實,即對于任何位A:

(A & 0 = 0) — 和0進行與運算,位總是會變成0。

(A & 1 = A) — 和1進行與運算,位總是保持不變。

舉個例子,假設(shè)我們有一個8位的整數(shù),我們希望確保前面的4位被關(guān)閉(置為0)。我們可以用&操作符來實現(xiàn):

首先,創(chuàng)建一個位掩碼,其效果是關(guān)閉8位整數(shù)的前4位。該位掩碼將為0B111110000。請注意,位掩碼的前4位設(shè)置為0,而其他每一位設(shè)置為1。

接下來,使用8位整數(shù)和創(chuàng)建的位掩碼進行 &操作。

const mask = 0b11110000;

// 222 => 11011110

// (222 & mask)
// ------------
// 11011110
// & 11110000
// ------------
// = 11010000
// ------------
// = 208 (decimal)

console.log(222 & mask); // 208
檢查設(shè)定位

&操作符還有一些其他有用的位屏蔽應(yīng)用。一個這樣的應(yīng)用是確定給定的位序列是否設(shè)置了一個或多個位。例如,假設(shè)我們要檢查是否為給定的十進制數(shù)設(shè)置了第五位。以下是我們?nèi)绾问褂?運算符來執(zhí)行此操作:

首先,創(chuàng)建一個位掩碼,用于檢查目標(biāo)位(在本例中為第五位)是否設(shè)置為1。位掩碼上的每個位都設(shè)置為0,但目標(biāo)位置的位除外,目標(biāo)位置的位設(shè)置為1。二進制數(shù)文字可用于輕松實現(xiàn)這一點:

const mask = 0b10000;

接下來,使用十進制數(shù)和位掩碼作為操作數(shù)執(zhí)行&操作,并將結(jié)果與位掩碼進行比較。如果所有目標(biāo)位都設(shè)置為十進制數(shù),&操作的結(jié)果將等于位掩碼。請注意,位掩碼中的0位將有效地關(guān)閉十進制數(shù)中的相應(yīng)位,因為a&0=0。

// 34 => 100010
// (34 & mask) => (100010 & 010000) = 000000
console.log((34 & mask) === mask); // false

// 50 => 110010
// (50 & mask) => (110010 & 010000) = 010000
console.log((50 & mask) === mask); // true

奇數(shù)或偶數(shù)

使用&運算符檢查十進制數(shù)的設(shè)定位可以擴展到檢查給定的十進制數(shù)是偶數(shù)還是奇數(shù)。為了實現(xiàn)這一點,使用1作為位掩碼(以確定是否設(shè)置了第一位或最右邊的位)。

對于整數(shù),可以使用最低有效位(第一位或最右邊的位)來確定數(shù)字是偶數(shù)還是奇數(shù)。如果啟用最低有效位(設(shè)置為1),則數(shù)字為奇數(shù);否則,數(shù)字為偶數(shù)。

function isOdd (int) {
  return (int & 1) === 1;
}

function isEven (int) {
  return (int & 1) === 0;
}

console.log(isOdd(34)); // false
console.log(isOdd(-63)); // true
console.log(isEven(-12)); // true
console.log(isEven(199)); // false
有用的標(biāo)識

在繼續(xù)下一個運算符之前,這里有一些&操作符的有用標(biāo)識(對于任何帶符號的32位整數(shù)A):

(A & 0) === 0
(A & ~A) === 0
(A & A) === A
(A & -1) === A
按位或(|)

運算符對其操作數(shù)的每對對應(yīng)位執(zhí)行“或”運算。運算符僅當(dāng)兩個位都為0時返回0;否則返回1。

對于一對位,這里是或操作的可能值:

(0 | 0) === 0
(0 | 1) === 1
(1 | 0) === 1
(1 | 1) === 1
"打開"位

在位屏蔽應(yīng)用中,可以使用運算符來確保位序列中的某些位被打開(設(shè)置為1)。這是基于這樣一個事實:對于任何給定的位A:

(A | 0 = A) — 和0進行或運算,位總是會保持不變。

(A | 1 = 1) — 和1進行或運算,位總是為1。

例如,假設(shè)我們有一個8位整數(shù),我們希望確保所有偶數(shù)位(第二、第四、第六、第八)都打開(設(shè)置為1)。| 運算符可用于實現(xiàn)以下目的:

首先,創(chuàng)建一個位掩碼,其效果是打開8位整數(shù)的每個偶數(shù)位。該位掩碼將是0B101010。請注意,位掩碼的偶數(shù)位設(shè)置為1,而其他位設(shè)置為0。

接下來,使用8位整數(shù)和創(chuàng)建的位掩碼執(zhí)行或操作:

const mask = 0b10101010;

// 208 => 11010000

// (208 | mask)
// ------------
// 11010000
// | 10101010
// ------------
// = 11111010
// ------------
// = 250 (decimal)

console.log(208 | mask); // 250
有用的標(biāo)識

在繼續(xù)下一個運算符之前,這里有一些 | 操作符的有用標(biāo)識(對于任何帶符號的32位整數(shù)A):

(A | 0) === A
(A | ~A) === -1
(A | A) === A
(A | -1) === -1
按位異或(^)

^運算符對其操作數(shù)的每對對應(yīng)位執(zhí)行異或(異或)運算。如果兩個位相同(0或1),則^運算符返回0;否則,它返回1。

對于一對位,下面是可能的值:

(0 ^ 0) === 0
(0 ^ 1) === 1
(1 ^ 0) === 1
(1 ^ 1) === 0
切換位

在位屏蔽應(yīng)用程序中,^ 運算符通常用于切換或翻轉(zhuǎn)位序列中的某些位。這是基于這樣一個事實:對于任何給定的位A:

0進行異或運算,位總是會保持不變。

(A ^ 0 = A)

當(dāng)與相應(yīng)的1位配對時,該位總是被切換。

(A ^ 1 = 1) — if A is 0
(A ^ 1 = 0) — if A is 1

例如,假設(shè)我們有一個8位整數(shù),我們希望確保除了最低有效位(第一位)和最高有效位(第八位)之外,每個位都被切換。可以使用^運算符實現(xiàn)以下目的:

首先,創(chuàng)建一個位掩碼,其效果是切換8位整數(shù)的每個位,除了最低有效位和最高有效位。該位掩碼將為0b0111110。請注意,要切換的位設(shè)置為1,而其他位設(shè)置為0。

接下來,使用8位整數(shù)和創(chuàng)建的位掩碼執(zhí)行^操作:

const mask = 0b01111110;

// 208 => 11010000

// (208 ^ mask)
// ------------
// 11010000
// ^ 01111110
// ------------
// = 10101110
// ------------
// = 174 (decimal)

console.log(208 ^ mask); // 174

有用的標(biāo)識

在繼續(xù)下一個運算符之前,以下是^操作的一些有用標(biāo)識(對于任何有符號的32位整數(shù)A):

(A ^ 0) === A
(A ^ ~A) === -1
(A ^ A) === 0
(A ^ -1) === ~A

從上面列出的標(biāo)識中可以明顯看出,-1上的xor操作等同于a上的按位非操作。因此,上面的foundIndex()函數(shù)也可以這樣編寫:

function foundIndex (index) {
  return Boolean(index ^ -1);
}
左移(<<)

左移位(<<)運算符接受兩個操作數(shù)。第一個操作數(shù)是整數(shù),而第二個操作數(shù)是要向左移動的第一個操作數(shù)的位數(shù)。零(0)位從右邊移入,而從左邊移入的多余位被丟棄。

例如,考慮整數(shù)170。假設(shè)我們要向左移動三位。我們可以使用<<運算符,如下所示:

// 170 => 00000000000000000000000010101010

// 170 << 3
// --------------------------------------------
//    (000)00000000000000000000010101010(***)
// --------------------------------------------
//  = (***)00000000000000000000010101010(000)
// --------------------------------------------
//  = 00000000000000000000010101010000
// --------------------------------------------
//  = 1360 (decimal)

console.log(170 << 3); // 1360

左移位位運算符(<<)可以使用以下javascript表達式定義:

(A << B) => A * (2 ** B) => A * Math.pow(2, B)

因此,回顧前面的示例:

(170 << 3) => 170 * (2 ** 3) => 170 * 8 => 1360
顏色轉(zhuǎn)換:RGB到十六進制

左移位(<)運算符的一個非常有用的應(yīng)用程序是將顏色從RGB表示轉(zhuǎn)換為十六進制表示。

RGB顏色的每個組件的顏色值在0-255之間。簡單地說,每個顏色值可以用8位完美地表示。

 0 => 0b00000000 (2進制) => 0x00 (16進制)
255 => 0b11111111 (2進制) => 0xff (16進制)

因此,顏色本身可以完美地用24位來表示(紅色、綠色和藍色分量各8位)。從右邊開始的前8位表示藍色分量,接下來的8位表示綠色分量,之后的8位表示紅色分量。

(binary) => 11111111 00100011 00010100

   (red) => 11111111 => ff => 255
 (green) => 00100011 => 23 => 35
  (blue) => 00010100 => 14 => 20

   (hex) => ff2314

既然我們已經(jīng)了解了如何將顏色表示為24位序列,那么讓我們來看看如何從顏色的各個組件的值組成顏色的24位。假設(shè)我們有一個用RGB(255、35、20)表示的顏色。以下是我們?nèi)绾谓M合這些位:

(red) => 255 => 00000000 00000000 00000000 11111111
(green) =>  35 => 00000000 00000000 00000000 00100011
 (blue) =>  20 => 00000000 00000000 00000000 00010100

// Rearrange the component bits and pad with zeroes as necessary
// Use the left shift operator

  (red << 16) => 00000000 11111111 00000000 00000000
 (green << 8) => 00000000 00000000 00100011 00000000
       (blue) => 00000000 00000000 00000000 00010100

// Combine the component bits together using the OR (|) operator
// ( red << 16 | green << 8 | blue )

      00000000 11111111 00000000 00000000
    | 00000000 00000000 00100011 00000000
    | 00000000 00000000 00000000 00010100
// -----------------------------------------
      00000000 11111111 00100011 00010100
// -----------------------------------------

既然過程非常清楚,下面是一個簡單的函數(shù),它將顏色的RGB值作為輸入數(shù)組,并基于上述過程返回顏色的相應(yīng)十六進制表示:

function rgbToHex ([red = 0, green = 0, blue = 0] = []) {
  return `#${(red << 16 | green << 8 | blue).toString(16)}`;
}
有符號右移(>>)

有符號右移(>>)運算符的符號接受兩個操作數(shù)。第一個操作數(shù)是整數(shù),而第二個操作數(shù)是要右移的第一個操作數(shù)的位數(shù)。

已移到右邊的多余位將被丟棄,而符號位(最左邊的位)的副本將從左邊移入。所以,整數(shù)的符號位會一直保留。所以這種運算叫做有符號右移。

例如,考慮整數(shù)170和-170。假設(shè)我們想把三位移到右邊。我們可以使用>>運算符,如下所示:

//  170 => 00000000000000000000000010101010
// -170 => 11111111111111111111111101010110

// 170 >> 3
// --------------------------------------------
//    (***)00000000000000000000000010101(010)
// --------------------------------------------
//  = (000)00000000000000000000000010101(***)
// --------------------------------------------
//  = 00000000000000000000000000010101
// --------------------------------------------
//  = 21 (decimal)

// -170 >> 3
// --------------------------------------------
//    (***)11111111111111111111111101010(110)
// --------------------------------------------
//  = (111)11111111111111111111111101010(***)
// --------------------------------------------
//  = 11111111111111111111111111101010
// --------------------------------------------
//  = -22 (decimal)

console.log(170 >> 3); // 21
console.log(-170 >> 3); // -22

通過以下javascript表達式可以描述有符號右移:

(A >> B) => Math.floor(A / (2 ** B)) => Math.floor(A / Math.pow(2, B))

因此,之前的那個例子可以如下表示:

(170 >> 3) => Math.floor(170 / (2 ** 3)) => Math.floor(170 / 8) => 21
(-170 >> 3) => Math.floor(-170 / (2 ** 3)) => Math.floor(-170 / 8) => -22
顏色提取

有符號右移(>>)運算符的一個非常好的應(yīng)用是從顏色中提取RGB顏色值。當(dāng)顏色以RGB表示時,很容易區(qū)分紅色、綠色和藍色顏色分量值。但是,對于以十六進制表示的顏色,這將花費更多的精力。

在上一節(jié)中,我們看到了從顏色的各個組成部分(紅色、綠色和藍色)的位組成顏色的過程。如果我們反向執(zhí)行這個過程,我們將能夠提取顏色的各個組成部分的值。讓我們試一試。

假設(shè)我們有一個用十六進制表示法ff2314表示的顏色。下面是顏色的有符號32位表示:

(color) => ff2314 (hexadecimal) => 11111111 00100011 00010100 (binary)

// 32-bit representation of color
00000000 11111111 00100011 00010100

為了獲得單個部分,我們將根據(jù)需要將顏色位按8的倍數(shù)右移,直到從右邊得到目標(biāo)組件位作為前8位。由于顏色的32位中的符號標(biāo)志位是0,因此我們可以安全地使用符號傳播右移位(>>)運算符。

color => 00000000 11111111 00100011 00010100

// Right shift the color bits by multiples of 8
// Until the target component bits are the first 8 bits from the right

  red => color >> 16
      => 00000000 11111111 00100011 00010100 >> 16
      => 00000000 00000000 00000000 11111111

green => color >> 8
      => 00000000 11111111 00100011 00010100 >> 8
      => 00000000 00000000 11111111 00100011

 blue => color >> 0 => color
      => 00000000 11111111 00100011 00010100

現(xiàn)在我們將目標(biāo)顏色位作為右前8位,我們需要一種方法來屏蔽除前8位之外的所有其他位。這使我們回到和(&)運算符。請記住,&運算符可用于確保關(guān)閉某些位。

讓我們從創(chuàng)建所需的位掩碼開始。就像這樣:

mask => 00000000 00000000 00000000 11111111
     => 0b11111111 (binary)
     => 0xff (hexadecimal)

準(zhǔn)備好位掩碼后,我們可以對上一次右移操作的每個結(jié)果執(zhí)行與(&)操作,使用位掩碼提取目標(biāo)顏色。

red => color >> 16 & 0xff
      =>   00000000 00000000 00000000 11111111
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 11111111
      =>   255 (decimal)

green => color >> 8 & 0xff
      =>   00000000 00000000 11111111 00100011
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 00100011
      =>   35 (decimal)

 blue => color & 0xff
      =>   00000000 11111111 00100011 00010100
      => & 00000000 00000000 00000000 11111111
      => = 00000000 00000000 00000000 00010100
      =>   20 (decimal)

基于上述過程,這里有一個簡單的函數(shù),它以十六進制顏色字符串(帶有六個十六進制數(shù)字)作為輸入,并返回相應(yīng)的RGB顏色分量值數(shù)組。

function hexToRgb (hex) {
  hex = hex.replace(/^#?([0-9a-f]{6})$/i, "$1");
  hex = Number(`0x${hex}`);

  return [
    hex >> 16 & 0xff, // red
    hex >> 8 & 0xff,  // green
    hex & 0xff        // blue
  ];
}
無符號右移(>>>)

無符號右移位(>>>)運算符的行為非常類似于符號傳播右移位(>>)運算符。然而,關(guān)鍵區(qū)別在于從左邊移入的位。

顧名思義,0位總是從左邊移入。因此,>>運算符始終返回?zé)o符號32位整數(shù),因為結(jié)果整數(shù)的符號位始終為0。對于正整數(shù),>>和>>>都將始終返回相同的結(jié)果。

例如,考慮整數(shù)170和-170。假設(shè)我們要將3位移到右邊,我們可以使用>>>操作符,如下所示:

//  170 => 00000000000000000000000010101010
// -170 => 11111111111111111111111101010110

// 170 >>> 3
// --------------------------------------------
//    (***)00000000000000000000000010101(010)
// --------------------------------------------
//  = (000)00000000000000000000000010101(***)
// --------------------------------------------
//  = 00000000000000000000000000010101
// --------------------------------------------
//  = 21 (decimal)

// -170 >>> 3
// --------------------------------------------
//    (***)11111111111111111111111101010(110)
// --------------------------------------------
//  = (000)11111111111111111111111101010(***)
// --------------------------------------------
//  = 00011111111111111111111111101010
// --------------------------------------------
//  = 536870890 (decimal)

console.log(170 >>> 3); // 21
console.log(-170 >>> 3); // 536870890
配置標(biāo)志

在總結(jié)本教程之前,讓我們考慮另一個非常常見的位操作符和位屏蔽應(yīng)用:配置標(biāo)志。

假設(shè)我們有一個函數(shù),它接受幾個布爾選項,這些選項可以用來控制函數(shù)的運行方式或返回的值的類型。創(chuàng)建此函數(shù)的一種可能方法是將所有選項作為參數(shù)傳遞給該函數(shù),可能使用一些默認(rèn)值,例如:

function doSomething (optA = true, optB = true, optC = false, optD = true, ...) {
  // something happens here...
}

當(dāng)然,這不太方便。在以下兩種情況下,這種方法開始變得相當(dāng)有問題:

假設(shè)我們有10個以上的布爾選項。我們不能用這么多參數(shù)定義函數(shù)。

假設(shè)我們只想為第五個和第九個選項指定一個不同的值,并讓其他選項保留默認(rèn)值。我們需要調(diào)用函數(shù),將默認(rèn)值作為所有其他選項的參數(shù)傳遞,同時為第五個和第九個選項傳遞所需的值。

用前面的方法解決問題的一種方法是為配置選項使用一個對象,如下所示:

const defaultOptions = {
  optA: true,
  optB: true,
  optC: false,
  optD: true,
  ...
};

function doSomething (options = defaultOptions) {
  // something happens here...
}

這種方法非常優(yōu)雅,您很可能已經(jīng)看到它被使用了,甚至自己在某個地方使用過。然而,使用這種方法時,options參數(shù)將始終是一個對象,對于配置選項來說,這可以被認(rèn)為是多余的。

如果所有選項都采用布爾值,則可以使用整數(shù)而不是對象來表示選項。在這種情況下,整數(shù)的某些位將映射到指定的選項。如果某個位被打開(設(shè)置為1),則指定選項的值為“真”;否則為“假”。

我們可以用一個簡單的例子來演示這種方法。假設(shè)我們有一個函數(shù),它規(guī)范化包含數(shù)字的數(shù)組列表中的項,并返回規(guī)范化的數(shù)組。返回的數(shù)組可以由三個選項控制,即:

fraction:將數(shù)組中的每個項除以數(shù)組中的最大項

unique:從數(shù)組中刪除重復(fù)項

sorted:將數(shù)組中的項從最低到最高排序

我們可以使用一個3位整數(shù)來表示這些選項,每個位都映射到一個選項。以下代碼段顯示選項標(biāo)志:

const LIST_FRACTION = 0x1; // (001)
const LIST_UNIQUE = 0x2;   // (010)
const LIST_SORTED = 0x4;   // (100)

要激活一個或多個選項,可以根據(jù)需要使用運算符組合相應(yīng)的標(biāo)志。例如,我們可以創(chuàng)建一個標(biāo)志來激活所有選項,如下所示:

const LIST_ALL = LIST_FRACTION | LIST_UNIQUE | LIST_SORTED; // (111)

同樣,假設(shè)我們只希望默認(rèn)情況下激活fraction和sorted選項。我們可以再次使用運算符,如下所示:

const LIST_DEFAULT = LIST_FRACTION | LIST_SORTED; // (101)

雖然只使用三個選項看起來并不糟糕,但當(dāng)有這么多選項時,它往往會變得非常混亂,并且默認(rèn)情況下需要激活其中的許多選項。在這種情況下,更好的方法是使用^運算符停用不需要的選項:

const LIST_DEFAULT = LIST_ALL ^ LIST_UNIQUE; // (101)

這里,我們有一個列表“所有”標(biāo)志,可以激活所有選項。然后,我們使用^運算符停用唯一選項,并根據(jù)需要保留其他選項。

現(xiàn)在我們已經(jīng)準(zhǔn)備好了選項標(biāo)志,可以繼續(xù)定義normalizelist()函數(shù):

function normalizeList (list, flag = LIST_DEFAULT) {
  if (flag & LIST_FRACTION) {
    const max = Math.max(...list);
    list = list.map(value => Number((value / max).toFixed(2)));
  }
  if (flag & LIST_UNIQUE) {
    list = [...new Set(list)];
  }
  if (flag & LIST_SORTED) {
    list = list.sort((a, b) => a - b);
  }
  return list;
}

為了檢查某個選項是否被激活,我們使用&運算符來檢查該選項的相應(yīng)位是否被打開(設(shè)置為1)。&操作是通過傳遞給函數(shù)的flag參數(shù)和選項的對應(yīng)標(biāo)志來執(zhí)行的,如下面的代碼段所示:

// Checking if the unique option is activated
// (flag & LIST_UNIQUE) === LIST_UNIQUE (activated)
// (flag & LIST_UNIQUE) === 0 (deactivated)

flag & LIST_UNIQUE
總結(jié)

嘿,我真的很高興你能讀完這篇文章,盡管讀了很長時間,但我強烈希望你在讀的時候?qū)W到一兩件事。謝謝你的時間。

正如我們在本文中所看到的,雖然使用得很謹(jǐn)慎,但javascript的位操作符有一些非常有趣的用例。我強烈希望您在閱讀本文的過程中獲得的見解從現(xiàn)在起用在你的日常開發(fā)中。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/110056.html

相關(guān)文章

  • 】11 種在大多數(shù)教程中找不到JavaScript技巧

    摘要:否則,將返回空數(shù)組的長度。該提案目前處于第階段,作為一項實驗性功能。轉(zhuǎn)換為布爾值除了常規(guī)的布爾值和之外,還將所有其他值視為或。這也可以用于將布爾值轉(zhuǎn)換為數(shù)字,如下所示在某些上下文中,將被解釋為連接操作符,而不是加法操作符。 譯者:前端小智 原文:medium.com/@bretcamero… 當(dāng)我開始學(xué)習(xí)JavaScript時,我把我在別人的代碼、code challenge網(wǎng)站以及我使用...

    EastWoodYang 評論0 收藏0
  • 由left-pad扯到JS中位運算

    摘要:原碼補碼和反碼原碼一個數(shù)在計算機中是以二進制的形式存在的,其中第一位存放符號正數(shù)為負(fù)數(shù)為。中的位運算在中按位操作符會將其操作數(shù)轉(zhuǎn)成補碼形式的有符號位整數(shù)。原文鏈接由扯到中的位運算 這個話題的由來是2016年3月份的時候 NPM 社區(qū)發(fā)生了‘left-pad’事件,不久后社區(qū)就有人發(fā)布了用來補救的,也是現(xiàn)在大家能用到的 left-pad 庫。 最開始這個庫的代碼是這樣的。 module....

    LeoHsiun 評論0 收藏0
  • 2021-09-08 交換兩個變量

    摘要:千里之行始于足下題目交換兩個變量不允許使用臨時變量思路首先大家一定需要深入了解在語言中按位異或操作符的作用,不懂的建議大家去百度。 千里之行始于足下 題目: 交...

    wangshijun 評論0 收藏0
  • 有趣JavaScript原生數(shù)組函數(shù)

    摘要:對的描述如下將會給數(shù)組里的每一個元素執(zhí)行一遍回調(diào)函數(shù),直到回調(diào)函數(shù)返回。的運行原理和類似,但回調(diào)函數(shù)是返回而不是。回調(diào)函數(shù)只會對已經(jīng)指定值的數(shù)組項調(diào)用。 showImg(http://fw008950-flywheel.netdna-ssl.com/wp-content/uploads/2013/11/JavaScript_Array_Functions_Header.jpg); 在...

    oliverhuang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<