成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

淺談JavaScript位操作符

fasss / 683人閱讀

摘要:有符號(hào)的右移操作符由兩個(gè)大于符號(hào)表示這個(gè)操作符的含義就是將數(shù)值的位向右移指定的位數(shù)同時(shí)保留符號(hào)位的值正負(fù)號(hào)標(biāo)記有符號(hào)的右移操作符與左移操作符剛好相反比如向右移動(dòng)位就是同樣的在移位的過程中也會(huì)出

位操作符的基本概念

因?yàn)?b>ECMAscript中所有數(shù)值都是以IEEE-75464格式存儲(chǔ),所以才會(huì)誕生了位操作符的概念.

位操作符作用于最基本的層次上,因?yàn)閿?shù)值按位存儲(chǔ),所以位操作符的作用也就是操作數(shù)值的位.不過位操作符并不能操作64位的值.所以位操作符會(huì)先將64位的值轉(zhuǎn)換成32位的值,然后執(zhí)行操作,最后再將結(jié)果轉(zhuǎn)換成64位的值.

但對(duì)于開發(fā)人員來說,這整個(gè)過程就像是只存在32位的數(shù)值一樣,這是因?yàn)?b>64位存儲(chǔ)格式是透明的.

當(dāng)然這里所說的數(shù)值指的是整數(shù).在對(duì)于有符號(hào)的整數(shù)中,32位的前31位用于表示整數(shù)的值,而第32位則表示整數(shù)的符號(hào)(即0表示正數(shù),1表示負(fù)數(shù)),我們把這第32個(gè)表示符號(hào)的位叫做符號(hào)位,符號(hào)位也決定了其它位的數(shù)值的格式.

正數(shù)都是按純二進(jìn)制格式存儲(chǔ)的,在前31位中的每一個(gè)位都表示2的冪.即第一位表示2^0(2的零次方),第二位表示2^1(2的1次方),依次類推.第一位也叫做位0,后面依次類推,第32位就叫做位31,其它沒有用到的位都以0填充,也可以被忽略不計(jì).

比如十進(jìn)制整數(shù)10的二進(jìn)制表示是0000 0000 0000 0000 0000 0000 0000 1010或者更簡(jiǎn)單的1010。這是4個(gè)有效位,這4位就決定了實(shí)際的值.在前面說到過可以用toString()方法指定參數(shù)可以表示將一個(gè)十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù).所以我在這里寫了一個(gè)函數(shù),表示將一個(gè)十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù),如下圖所示:

既然二進(jìn)制數(shù)1010就是十進(jìn)制數(shù)10,那么我們還可以將這個(gè)二進(jìn)制數(shù)轉(zhuǎn)換成十進(jìn)制數(shù),是如何計(jì)算的呢?很簡(jiǎn)單,因?yàn)槎M(jìn)制數(shù)最后一位表示符號(hào),所以不計(jì),這里的101各代表冪數(shù)為3,2,1,這也是為什么十進(jìn)制轉(zhuǎn)換成二進(jìn)制數(shù)要取余數(shù)倒排的原因,然后將位上的數(shù)乘以基數(shù)2的冪數(shù).也就是說可以寫成等式2 ^ 3 * 1 + 2 ^ 2 * 0 + 2 ^ 1 * 1 = 10.(2 ^ *表示2*次方).

負(fù)數(shù)同樣以二進(jìn)制碼存儲(chǔ),只不過與正數(shù)有點(diǎn)區(qū)別,區(qū)別就是負(fù)數(shù)的格式是二進(jìn)制補(bǔ)碼.在求二進(jìn)制補(bǔ)碼的時(shí)候,有以下三個(gè)規(guī)則:

(1).先求出這個(gè)負(fù)數(shù)的絕對(duì)值的二進(jìn)制碼.比如十進(jìn)制數(shù)-17,就是先求17的二進(jìn)制碼.

(2).然后求二進(jìn)制碼的反碼,就是將0變成1,1變成0.

(3)最后將得到的二進(jìn)制反碼加1.

比如說求十進(jìn)制數(shù)-10的二進(jìn)制碼,我們要先求10的二進(jìn)制碼,也就是
0000 0000 0000 0000 0000 0000 0000 1010,然后取反碼就是
1111 1111 1111 1111 1111 1111 1111 0101,最后加1,但因?yàn)槎M(jìn)制數(shù)只能是1或者0表示,所以1+1大于2的話,就會(huì)向前進(jìn)位1.所以這個(gè)反碼加1最后得到的值應(yīng)該是1111 1111 1111 1111 1111 1111 1111 0110.而這個(gè)也是-10的二進(jìn)制表示.需要注意的是在處理有符號(hào)的整數(shù)的時(shí)候,是訪問不到第32位的(也就是位31).

但在實(shí)際情況中,ECMAscript是會(huì)盡力向我們隱藏所有的這些信息.也就是說在實(shí)際轉(zhuǎn)換負(fù)數(shù)的二進(jìn)制碼時(shí),它只會(huì)將這個(gè)負(fù)數(shù)的絕對(duì)值的二進(jìn)制碼前面加上一個(gè)負(fù)號(hào),就表示這個(gè)負(fù)數(shù)的二進(jìn)制碼.如下圖所示:

這個(gè)轉(zhuǎn)換過程說明ECMAscript解析引擎理解了二進(jìn)制補(bǔ)碼并將其以更合乎邏輯的形式展示出來.

在默認(rèn)情況下,ECMAscript中的所有整數(shù)都是有符號(hào)整數(shù).當(dāng)然也存在無符號(hào)整數(shù),對(duì)于無符號(hào)的整數(shù)來說,第32位不會(huì)再表示符號(hào),因?yàn)闊o符號(hào)整數(shù)只能是正整數(shù).而且無符號(hào)整數(shù)的值可以更大,因?yàn)榈?b>32位不再表示符號(hào),而可以表示成數(shù)值.什么意思呢?就是說當(dāng)我們?cè)賹⑹M(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù)時(shí),必須要除到商為0時(shí),才會(huì)倒排余數(shù),而第32位恰好就是商為0的那個(gè)余數(shù).而正整數(shù)值越大,我們可以省略的有效位數(shù)就越多,此時(shí)值也就越大.

ECMAscript中,當(dāng)對(duì)數(shù)值應(yīng)用位操作符的時(shí)候,雖然后臺(tái)會(huì)發(fā)生將64位數(shù)值轉(zhuǎn)換成32位數(shù)值,然后執(zhí)行完操作之后,再轉(zhuǎn)換成64位的數(shù)值這個(gè)轉(zhuǎn)換過程.但正因?yàn)檫@個(gè)轉(zhuǎn)換過程導(dǎo)致了一個(gè)嚴(yán)重的副效應(yīng),也就是說在對(duì)特殊的NaNInfinity值應(yīng)用位操作符時(shí),這兩個(gè)值會(huì)被當(dāng)成0來處理.

而如果對(duì)非數(shù)值應(yīng)用位操作符,會(huì)自動(dòng)使用Number()函數(shù)將其轉(zhuǎn)換成一個(gè)數(shù)值來操作,然后再應(yīng)用位操作符,得到的結(jié)果也將是一個(gè)數(shù)值.

總的說來,位操作符主要包含按位非(NOT),按位與(AND),按位或(OR),按位異或(XOR),左移,無符號(hào)右移和有符號(hào)右移7個(gè)操作符.接下來,咱們就來一一分析這7個(gè)操作符.

a.按位非(NOT)

按位非用一個(gè)波浪線符號(hào)"~"表示,執(zhí)行按位非的結(jié)果就是取得數(shù)值的反碼.它也是ECMAscript中少數(shù)幾個(gè)與二進(jìn)制計(jì)算相關(guān)的操作符.

比如求10的按位非結(jié)果,那么按照求二進(jìn)制得到10的二進(jìn)制碼是0000 0000 0000 0000 0000 0000 0000 1010,然后取反碼就是1111 1111 1111 1111 1111 1111 1111 0101.而要將這個(gè)反碼轉(zhuǎn)換成十進(jìn)制數(shù),還需要以下過程:

此時(shí),位31上的1代表符號(hào)為負(fù),因?yàn)樨?fù)數(shù)的補(bǔ)碼就是反碼加1,所以得知負(fù)數(shù)的反碼就等于補(bǔ)碼減1,所以此時(shí)求得負(fù)數(shù)的反碼是1111 1111 1111 1111 1111 1111 1111 0100,所以負(fù)數(shù)的原碼就是取反,變成了0000 0000 0000 0000 0000 0000 0000 1011,所以此時(shí)再將這個(gè)二進(jìn)制數(shù)轉(zhuǎn)換成十進(jìn)制數(shù)就是-(2 ^ 3 * 1 + 2 ^ 2 * 0 + 2 ^ 1 * 1 + 2 ^ 0 * 1)=-11.要理清這個(gè)轉(zhuǎn)換過程,需要知道什么是反碼,什么是原碼,什么又是補(bǔ)碼,因?yàn)閰⑴c計(jì)算的是補(bǔ)碼,而要轉(zhuǎn)換的是求原碼.也就是說,要想將二進(jìn)制反碼轉(zhuǎn)換成十進(jìn)制數(shù),就必須求得二進(jìn)制反碼的原碼,然后對(duì)原碼直接按照二進(jìn)制轉(zhuǎn)換成十進(jìn)制的方式來計(jì)算轉(zhuǎn)換.現(xiàn)在我們來驗(yàn)證一下是否是我們所想的,如下圖所示:

再比如求-10的按位非結(jié)果,按照理論分析,我們從前述可以得知最終-10的二進(jìn)制碼為1111 1111 1111 1111 1111 1111 1111 0110,取反碼就變成了0000 0000 0000 0000 0000 0000 0000 1001,而此時(shí)的二進(jìn)制反碼的補(bǔ)碼,原碼都一樣,所以直接計(jì)算就是2 ^ 3 * 1 + 2 ^ 2 * 0 + 2 ^ 1 * 0 + 2 ^ 0 * 1 = 9.如下圖所示:

通過以上示例還應(yīng)該得到一個(gè)結(jié)論:正整數(shù)的二進(jìn)制碼的反碼與原碼補(bǔ)碼不一致,而負(fù)整數(shù)的二進(jìn)制碼的反碼就與原碼補(bǔ)碼一致.換句話說,就是正數(shù)的原碼與補(bǔ)碼一樣,負(fù)數(shù)的原碼與補(bǔ)碼不一樣.

如果實(shí)在是不能理解原碼,補(bǔ)碼與反碼,可以直接把這個(gè)操作符理解為數(shù)值加1取反.如101取反就變成-11,-101取反就變成9.

而實(shí)際上,對(duì)按位非的結(jié)果比如~10~-10,我們還可以寫成如下圖所示的表示:

我們可以用變量來表示,如下圖所示:

雖然不用按位非操作符的以上所表示的代碼也能輸出同樣的結(jié)果,但由于按位非是對(duì)底層進(jìn)行操作,所以使用按位非操作符的速度會(huì)更快.

b.按位與(AND)

按位與操作符用一個(gè)和號(hào)字符(&)表示,它有兩個(gè)操作數(shù),從本質(zhì)上講,按位與操作就是將數(shù)值的每一位二進(jìn)制碼對(duì)齊,然后根據(jù)以下規(guī)則,對(duì)相同為止上的兩個(gè)數(shù)執(zhí)行AND操作.規(guī)則如下:

  第一個(gè)數(shù)值的位 ?  ? ?? ?     第二個(gè)數(shù)值的位 ? ? ? ? ?   結(jié)果
    1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1 ? ? ? ? ? ? ? ? ? ? 1
    1 ? ? ? ? ? ? ? ? ? ? ? ?   ? 0 ? ? ? ? ? ? ? ? ? ? 0
    0 ? ? ? ? ? ? ? ? ? ? ?     ? 1 ? ? ? ? ? ? ? ? ? ? 0
    0 ? ? ? ? ? ? ? ? ? ?         0 ? ? ? ? ? ? ? ? ? ? 0

簡(jiǎn)而言之,就是只在兩個(gè)數(shù)值的位數(shù)都對(duì)應(yīng)為1的時(shí)候,結(jié)果才為1,任何一位是0,結(jié)果都是0.

如以下示例:

對(duì)106進(jìn)行按位與操作時(shí)返回2,這是為什么呢?請(qǐng)看底層原理:

首先10轉(zhuǎn)換成二進(jìn)制數(shù)就是0000 0000 0000 0000 0000 0000 0000 1010,而6轉(zhuǎn)換成二進(jìn)制數(shù)則是0000 0000 0000 0000 0000 0000 0000 0110.過程可以如下:

10 =?0000 0000 0000 0000 0000 0000 0000 1010
?6 ?= 0000 0000 0000 0000 0000 0000 0000 0110
——————————————————————————————————————————————
AND =?0000 0000 0000 0000 0000 0000 0000 0010

然后按位與結(jié)果轉(zhuǎn)換成十進(jìn)制數(shù)就是2 ^ 1 * 1 = 2.所以最終結(jié)果為2.

再比如求2 & 5的結(jié)果,現(xiàn)在咱們按照步驟來計(jì)算出結(jié)果,然后再驗(yàn)證答案對(duì)不對(duì).

首先求得2的二進(jìn)制數(shù)為0000 0000 0000 0000 0000 0000 0000 0010,5的二進(jìn)制數(shù)為0000 0000 0000 0000 0000 0000 0000 0101。?

 2 =?0000 0000 0000 0000 0000 0000 0000 0010
?5 ?=?0000 0000 0000 0000 0000 0000 0000 0101
——————————————————————————————————————————————
AND =?0000 0000 0000 0000 0000 0000 0000 0000

而這個(gè)結(jié)果轉(zhuǎn)換成十進(jìn)制數(shù)就是0。所以得出結(jié)果是0,現(xiàn)在咱們來驗(yàn)證一下,如下圖所示:

c.按位或(OR)

? ?按位或操作符由一個(gè)豎線符號(hào)(|)表示,同樣也有兩個(gè)操作數(shù).從本質(zhì)上講,也可以說是將數(shù)值的二進(jìn)制碼對(duì)齊,但與按位與操作符有一點(diǎn)點(diǎn)區(qū)別,就是它的規(guī)則與按位與操作符不一樣,具體如下:

第一個(gè)數(shù)值的位 ?  ? ?? ?     第二個(gè)數(shù)值的位 ? ? ? ? ?  ? ?結(jié)果
    1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1 ? ? ? ? ? ? ? ? ? ? ?1
    1 ? ? ? ? ? ? ? ? ? ? ? ?   ? 0 ? ? ? ? ? ? ? ? ? ?  1
    0 ? ? ? ? ? ? ? ? ? ? ?     ? 1 ? ? ? ? ? ? ? ? ? ? ?1
    0 ? ? ? ? ? ? ? ? ? ?         0 ? ? ? ? ? ? ? ? ? ? ?0

簡(jiǎn)而言之,就是按位或操作符只有其對(duì)應(yīng)的兩個(gè)位都是0的情況下才是0,其它有一個(gè)位是1的情況下都是1.如以下示例:

現(xiàn)在,我們就來分析一下為什么結(jié)果是7,其實(shí)與按位與的底層操作很相似,2和5的二進(jìn)制數(shù)前述示例已求得:

2 =?0000 0000 0000 0000 0000 0000 0000 0010
5 ?=?0000 0000 0000 0000 0000 0000 0000 0101
——————————————————————————————————————————————
OR =?0000 0000 0000 0000 0000 0000 0000 0111

而將按位或的結(jié)果轉(zhuǎn)換成十進(jìn)制數(shù)就是2 ^ 2 * 1 + 2 ^ 1 * 1 + 2 ^ 0 * 1 = 7。所以結(jié)果7就是這么求來的。

d.按位異或(XOR)

?按位異或操作符由一個(gè)插入符號(hào)(^)表示,也有兩個(gè)操作數(shù),其本質(zhì)也與按位與和按位或操作符相同,但其規(guī)則也不一樣,如下:

第一個(gè)數(shù)值的位 ?  ? ?? ?第二個(gè)數(shù)值的位 ? ? ? ? ?  ? ?結(jié)果
    1 ? ? ? ? ? ? ? ? ? ? ?1 ? ? ? ? ? ? ? ? ? ? ? ?0
    1 ? ? ? ? ? ? ? ? ? ? ?0 ? ? ? ? ? ? ? ? ? ?    1
    0 ? ? ? ? ? ? ? ? ? ? ?1 ? ? ? ? ? ? ? ? ? ? ? ?1
    0 ? ? ? ? ? ? ? ? ? ?  0 ? ? ? ? ? ? ? ? ? ? ? ?0

也就是說,按位異或操作符只有在其中一個(gè)位為1時(shí)才返回1,否則就是0。如對(duì)2 ^ 5求結(jié)果如下圖:

現(xiàn)在來分析一下為什么結(jié)果是7,過程也與求按位與和按位或結(jié)果一致.

2 =?0000 0000 0000 0000 0000 0000 0000 0010
5 ?=?0000 0000 0000 0000 0000 0000 0000 0101
——————————————————————————————————————————————
XOR =?0000 0000 0000 0000 0000 0000 0000 0111

這里因?yàn)閷?duì)應(yīng)位沒有變化,所以最終結(jié)果才會(huì)和按位或結(jié)果一致。

e.左移

? 左移操作符由兩個(gè)小于號(hào)(<<)表示,也是兩個(gè)操作數(shù),第一個(gè)操作數(shù)就表示要左移的數(shù)值,第二個(gè)操作數(shù)表示左移的位數(shù).所以左移操作符的含義就是將數(shù)值的所有位向左移動(dòng)指定的位數(shù).

而在向左移動(dòng)了指定的左移位數(shù)之后,原數(shù)值的右側(cè)會(huì)多出指定的位數(shù)個(gè)空位(比如指定左移4位,也就多出4個(gè)空位,依次類推)出來,不過左移操作會(huì)自動(dòng)以0來填充這些空位.

如以下示例:

現(xiàn)在來分析一下為什么結(jié)果是40,首先5的二進(jìn)制數(shù)是
0000 0000 0000 0000 0000 0000 0000 0101,指定的是向左移動(dòng)3位,所以整體向左移動(dòng)3位,就變成了0000 0000 0000 0000 0000 0000 0010 ?1000,而這個(gè)二進(jìn)制轉(zhuǎn)換成十進(jìn)制數(shù)就是2 ^ 5 * 1 + 2 ^ 3 * 1 = 40.
所以最終結(jié)果就是40.

注意,左移操作并不會(huì)影響操作數(shù)的符號(hào)位,換句話說,如果將-5左移3位,結(jié)果將是-40,而不是40.

f.右移操作符

?右移操作符又分為無符號(hào)右移有符號(hào)右移操作符.

(1).有符號(hào)的右移操作符。

?有符號(hào)的右移操作符由兩個(gè)大于符號(hào)表示(>>),這個(gè)操作符的含義就是將數(shù)值的位向右移指定的位數(shù),同時(shí)保留符號(hào)位的值(正負(fù)號(hào)標(biāo)記),有符號(hào)的右移操作符與左移操作符剛好相反,比如40向右移動(dòng)3位就是5.

同樣的,在移位的過程中,也會(huì)出現(xiàn)空位,而這時(shí)候,ECMAscript會(huì)用符號(hào)位的值來填充所有空位,也就是說每向右移動(dòng)一位,移走的位上的數(shù)不管是1,還是0都會(huì)消失了,則會(huì)在數(shù)值的左側(cè)補(bǔ)充一位,而這位的值就是符號(hào)位的值,即如果是正數(shù),補(bǔ)充0,負(fù)數(shù)補(bǔ)充1.

如以下一個(gè)示例:

現(xiàn)在,咱們就來分析分析為什么最終結(jié)果為0.首先由前述可以得知40的二進(jìn)制數(shù)為0000 0000 0000 0000 0000 0000 0010 ?1000,指定的是向右移動(dòng)3位,那么整體向右移就變成了0000 0000 0000 0000 0000 0000 0000 0101,這個(gè)轉(zhuǎn)換成十進(jìn)制數(shù)也就是5.所以才會(huì)說有符號(hào)的右移與左移結(jié)果相反.

再來看一個(gè)示例:

現(xiàn)在,咱們就來分析分析為什么最終結(jié)果為0.首先由前述可以得知5的二進(jìn)制數(shù)為0000 0000 0000 0000 0000 0000 0000 0101,指定的是向右移動(dòng)3位,那么整體向右移3位,左側(cè)就要補(bǔ)充符號(hào)位的值,因?yàn)槭钦龜?shù)(正數(shù)符號(hào)表示為0),所以補(bǔ)充3個(gè)0,就變成了
0000 0000 0000 0000 0000 0000 0000 0000.所以最終結(jié)果為0

如果這樣不能理解的話,那么假設(shè)向右移動(dòng)一位,也就是求5 >> 1的結(jié)果,同樣在最左側(cè)補(bǔ)充一個(gè)符號(hào)位的值0,右移走了末位的1.所以變成了0000 0000 0000 0000 0000 0000 0000 0010.這個(gè)轉(zhuǎn)換成十進(jìn)制數(shù)就是2.現(xiàn)在咱們來操作驗(yàn)證一下,如下圖:

(2).無符號(hào)右移操作符。

? ?無符號(hào)右移操作符由三個(gè)大于符號(hào)表示(>>>).這個(gè)操作符也是會(huì)將所有的32位都整體向右移動(dòng)指定的位數(shù).對(duì)于正數(shù)來說,其實(shí)無符號(hào)右移操作符和有符號(hào)右移操作符的結(jié)果一致.

5 >>> 1仍然是2,按照同樣的過程步驟分析.

對(duì)于正數(shù)沒有什么變化,但對(duì)于負(fù)數(shù)來說,變化可就大了,首先無符號(hào)右移操作符是以0填充空位,而不是像有符號(hào)右移操作符那樣以符號(hào)位的值填充.所以才會(huì)正數(shù)與有符號(hào)右移操作符的結(jié)果相同.但是負(fù)數(shù)就不一樣了,無符號(hào)右移操作符會(huì)把負(fù)數(shù)的二進(jìn)制碼當(dāng)成正數(shù)的二進(jìn)制碼,而且負(fù)數(shù)是由其絕對(duì)值的二進(jìn)制補(bǔ)碼表示,因此導(dǎo)致無符號(hào)右移之后結(jié)果會(huì)很大.換句話說,就是對(duì)負(fù)數(shù)進(jìn)行無符號(hào)右移操作時(shí)只會(huì)返回正數(shù).

如求-5 >>> 3.我們先自己求一遍,首先-5的二進(jìn)制補(bǔ)碼為1111 1111 1111 1111 1111 1111 1111 1010,而因?yàn)闊o符號(hào)右移會(huì)把這個(gè)補(bǔ)碼當(dāng)成正數(shù)的二進(jìn)制碼,所以轉(zhuǎn)換成十進(jìn)制數(shù)就是(口算不太現(xiàn)實(shí),太大了,還是讓計(jì)算機(jī)來算吧)如下圖所示:

所以就會(huì)被當(dāng)成4294967290,然后這個(gè)正數(shù)的二進(jìn)制碼右移3位變成了0001?1111 1111 1111 1111 1111 1111 1111,轉(zhuǎn)換成十進(jìn)制數(shù)就是如下圖所示:

所以最終結(jié)果就是536870911.現(xiàn)在,我們來驗(yàn)證一下,如下圖所示:

前端面試題分析

知道了位操作符之后,現(xiàn)在咱們來分析一道題,有這樣一道前端面試題,寫一個(gè)函數(shù)用于判斷一個(gè)非負(fù)整數(shù)是否是2的非負(fù)整數(shù)次冪.而有人曾經(jīng)這樣寫,如下圖所示:

那么為什么這樣寫呢,我們來分析一下這其中原理,首先什么是函數(shù),使用function關(guān)鍵字聲明的都可以被叫做函數(shù),而這里定義的函數(shù)名也比較語義化,叫做isPowerOfTwo,圓括號(hào)中的n叫做函數(shù)的參數(shù),顧名思義,這里的參數(shù)就是傳入一個(gè)非負(fù)整數(shù).而這個(gè)函數(shù)的作用就是要判斷傳入的參數(shù)(即非負(fù)整數(shù))是否是2的非負(fù)整數(shù)次冪.

return也是一個(gè)關(guān)鍵字,表示返回一個(gè)值,用在函數(shù)當(dāng)中,而要記住的是,如果在函數(shù)當(dāng)中寫入了return關(guān)鍵字,在這個(gè)關(guān)鍵字表示的語句結(jié)束后面再寫其它語句是沒有效果的,如下圖所示:

如上圖所示,alert()方法表示彈出一個(gè)原生的彈出框,但實(shí)際上在調(diào)用這個(gè)定義的判斷函數(shù)之后,是不會(huì)執(zhí)行彈出框的,這就是return關(guān)鍵字在這里起到的作用.

現(xiàn)在再來分析一下里面的結(jié)構(gòu),嘆號(hào)(!)也就是邏輯非的意思,這個(gè)操作符會(huì)把一個(gè)操作數(shù)轉(zhuǎn)換成布爾值,然后取反.

再來看圓括號(hào)里面的和字符號(hào)&,在學(xué)了位操作符之后,我們就應(yīng)該知道這個(gè)符號(hào)就是按位與的意思,而按位與是操作二進(jìn)制數(shù)的位的,對(duì)應(yīng)規(guī)則也應(yīng)該知道,就是當(dāng)兩個(gè)操作數(shù)(在這里指nn-1)的對(duì)應(yīng)位都是1時(shí),最終返回的對(duì)應(yīng)位結(jié)果才是1,否則就是0.按位與的作用就是將位對(duì)齊.所以,在返回這個(gè)結(jié)果之前,我們還需要知道如何轉(zhuǎn)換成二進(jìn)制數(shù).

我們應(yīng)該知道對(duì)象的toString()方法,可以為其指定一個(gè)參數(shù)為基數(shù)2,就可以將一個(gè)操作數(shù)轉(zhuǎn)換成二進(jìn)制數(shù)返回,當(dāng)然這里也是返回一個(gè)字符串.而為了方便,我將這個(gè)方法封裝在一個(gè)函數(shù)中,如下圖所示:

現(xiàn)在我們?cè)賮砜纯匆粋€(gè)非負(fù)整數(shù)如果是2的冪,會(huì)有什么特點(diǎn),我們可以調(diào)用以上的定義函數(shù)將一個(gè)非負(fù)整數(shù)轉(zhuǎn)換成二進(jìn)制數(shù),而一個(gè)非負(fù)整數(shù)如果是2的冪,我們應(yīng)該知道2的冪有2 ^ 0 = 1,2 ^ 1 = 2,2 ^ 2 = 4......依次類推,我們從而得知1,2,4,8,16....等就是2的冪,而我們將這些值轉(zhuǎn)換成二進(jìn)制數(shù),就可以知道有什么樣的關(guān)系了,比如1轉(zhuǎn)換成二進(jìn)制就是1,2轉(zhuǎn)換成二進(jìn)制是10,4轉(zhuǎn)換成二進(jìn)制是100......依此類推,不信咱們可以用上面定義好的函數(shù)來驗(yàn)證,如下圖:

現(xiàn)在我們就應(yīng)該知道規(guī)律了,如果一個(gè)非負(fù)整數(shù)是2的非負(fù)整數(shù)次冪的話,那么這個(gè)數(shù)一定是上一個(gè)2的非負(fù)整數(shù)次冪的二進(jìn)制數(shù)左移了一位.而通過之前知道的左移操作符,我們知道,左移就是將位往左移動(dòng)一位,然后在移動(dòng)后的空位中以0填充.

現(xiàn)在,我們?cè)賮砜纯?b>n-1,假設(shè)是2的非負(fù)整數(shù)次冪的非負(fù)整數(shù),減1,然后再將其轉(zhuǎn)換成二進(jìn)制數(shù),比如12的非負(fù)整數(shù)次冪,1 - 1 = 0.轉(zhuǎn)換成二進(jìn)制就是0(這里是簡(jiǎn)寫),再比如2 - 1 = 1的二進(jìn)制就是1,4 - 1 = 3的二進(jìn)制就是11,7就是111.不信我們可以通過以上定義的函數(shù)來驗(yàn)證,如下圖所示:

通過使用按位與操作符取得非負(fù)整數(shù)與非負(fù)整數(shù)減1的結(jié)果,不言而喻,始終都會(huì)返回0,為什么呢?因?yàn)閷?duì)應(yīng)位的關(guān)系,我們?nèi)∑渲幸粋€(gè)為例子,如下:

0 = 0000?0000?0000?0000?0000?0000?0000?0000
1 = 0000?0000?0000?0000?0000?0000?0000?0001
——————————————————————————————————————————————
AND =?0000?0000?0000?0000?0000?0000?0000?0000

所以最終結(jié)果就是二進(jìn)制數(shù)0000?0000?0000?0000?0000?0000?0000?0000,轉(zhuǎn)換成十進(jìn)制數(shù)就是0.

這樣,我們就應(yīng)該知道了,如果這個(gè)非負(fù)整數(shù)是2的非負(fù)整數(shù)次冪的話,那么它與它減1兩個(gè)操作數(shù)取按位與結(jié)果就應(yīng)該是0.

而我們知道邏輯非操作符對(duì)數(shù)值0會(huì)返回true的布爾值,所以當(dāng)如果傳入的參數(shù)是非負(fù)整數(shù),并且還是2的非負(fù)整數(shù)次冪的話,那么這個(gè)函數(shù)最終就會(huì)返回true.我們可以直接調(diào)用這個(gè)函數(shù),如下圖所示:

理解和掌握JavaScript位操作符,有助于我們研究底層原理。

鄙人創(chuàng)建了一個(gè)QQ群,供大家學(xué)習(xí)交流,希望和大家合作愉快,互相幫助,交流學(xué)習(xí),以下為群二維碼:

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101960.html

相關(guān)文章

  • 淺談Javascript事件委托(代理)

    摘要:開玩笑啦,提供一種方法叫做事件委托。途中經(jīng)過各個(gè)層次的,并在各上觸發(fā)捕獲事件,直到到達(dá)時(shí)間的目標(biāo)。懂得了事件冒泡的過程,就很容易明白事件委托的運(yùn)作原理。 首先祝大家七夕快樂。。假如現(xiàn)在有一個(gè)的列表,里面可能會(huì)有若干個(gè)列表項(xiàng)。現(xiàn)在要為每一個(gè)列表項(xiàng)綁定相同的點(diǎn)擊事件,現(xiàn)在你可能會(huì)有這幾種做法: 手動(dòng)為每一個(gè)列表項(xiàng)綁定事件; 在onload的時(shí)候,找到該列表,對(duì)其每一個(gè)子元素進(jìn)行遍歷,循環(huán)...

    yunhao 評(píng)論0 收藏0
  • 淺談V8引擎中的垃圾回收機(jī)制

    摘要:新生代的對(duì)象為存活時(shí)間較短的對(duì)象,老生代中的對(duì)象為存活時(shí)間較長(zhǎng)或常駐內(nèi)存的對(duì)象。分別對(duì)新生代和老生代使用不同的垃圾回收算法來提升垃圾回收的效率。如果指向老生代我們就不必考慮它了。 這篇文章的所有內(nèi)容均來自 樸靈的《深入淺出Node.js》及A tour of V8:Garbage Collection,后者還有中文翻譯版V8 之旅: 垃圾回收器,我在這里只是做了個(gè)記錄和結(jié)合 垃圾回收...

    happen 評(píng)論0 收藏0
  • 淺談JS中的數(shù)據(jù)類型轉(zhuǎn)換

    摘要:關(guān)于中的各種數(shù)據(jù)類型的簡(jiǎn)單轉(zhuǎn)換。轉(zhuǎn)換為布爾值全局方法方法注意要區(qū)分空字符串和有空格的字符串。如果預(yù)期某個(gè)位置應(yīng)該是布爾值,會(huì)將該位置上現(xiàn)有的值自動(dòng)轉(zhuǎn)為布爾值。常規(guī)轉(zhuǎn)換取反兩次,對(duì)應(yīng)的布爾值不變。 關(guān)于JavaScript中的各種數(shù)據(jù)類型的簡(jiǎn)單轉(zhuǎn)換。 轉(zhuǎn)換為字符串 toString 可以用toString這個(gè)API將其他數(shù)據(jù)類型轉(zhuǎn)換為字符串,其中也有一些特例。 var a = 1; a....

    CarlBenjamin 評(píng)論0 收藏0
  • 淺談Java并發(fā)編程系列(七) —— 深入解析synchronized關(guān)鍵字

    摘要:第一個(gè)字被稱為。經(jīng)量級(jí)鎖的加鎖過程當(dāng)一個(gè)對(duì)象被鎖定時(shí),被復(fù)制到當(dāng)前嘗試獲取鎖的線程的線程棧的鎖記錄空間被復(fù)制的官方稱為。根據(jù)鎖對(duì)象目前是否處于被鎖定狀態(tài),撤銷偏向后恢復(fù)到未鎖定或經(jīng)量級(jí)鎖定狀態(tài)。 Synchronized關(guān)鍵字 synchronized的鎖機(jī)制的主要優(yōu)勢(shì)是Java語言內(nèi)置的鎖機(jī)制,因此,JVM可以自由的優(yōu)化而不影響已存在的代碼。 任何對(duì)象都擁有對(duì)象頭這一數(shù)據(jù)結(jié)構(gòu)來支持鎖...

    piglei 評(píng)論0 收藏0
  • 淺談布隆過濾器

    摘要:那該怎么辦,現(xiàn)在該介紹今天的主角了布隆過濾器就可以解決這樣的問題。具體介紹布隆過濾器實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制矢量和一系列隨機(jī)映射函數(shù)。布隆過濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。缺點(diǎn)布隆過濾器有寧可錯(cuò)殺一百,也不能放過一個(gè)的性質(zhì)。 1. 問題情景 如果面試官問你,一個(gè)網(wǎng)站有 100 億 url 存在一個(gè)黑名單中,每條 url 平均 64 字節(jié)。問這個(gè)黑名單要怎么存?若此時(shí)隨便輸入一...

    jone5679 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<