JavaScript模運算符理解及運用實戰(zhàn)
引言
本文翻譯自 Understanding the JavaScript Modulo Operator,作者:joshwcomeau, 略有刪改。
當(dāng)我第一次學(xué)習(xí)編碼時,我記得發(fā)現(xiàn)模運算符(%)非常令人困惑。??
當(dāng)你不明白它的原理的時候,它產(chǎn)生的值看起來完全是隨機的:
const what = 10 % 4; // 2 const the = 10 % 10; // 0 const heck = 4 % 10; // 4
在這篇文章中,我們將通過改進除法的心理模型來學(xué)習(xí)這個運算符是如何工作的,文末還將介紹一個實用的日常實踐。
受眾群體:
這篇博客文章是為初級到中級JavaScript開發(fā)人員所寫。一些JavaScript知識是假設(shè)的,但核心內(nèi)容應(yīng)該對每個人都有用!
重新思考
假設(shè)我們有下面的計算:
12 ÷ 4
除法常常讓人感覺非常抽象或理論化,但有一種實用的方法來思考它:我們可以把一個數(shù)字分成大小相等的組。
12 ÷ 4
的計算結(jié)果為3
,因為每個組正好包含3個項目。從本質(zhì)上講我們正在計算每個組中將包含多少個項目。
在上面的示例中我們的被除數(shù)是12。使用除法時,它可以用很多不同的方式來分割。
假設(shè)我們有以下等式:
11 ÷ 4
這個方程式的值為2.75。每組有2個完整的項目,然后是另一個項目的3/4。
如果我們分披薩或蛋糕,這是可行的。但如果這些物品是不可摧毀的呢?如果我們不能把每一項分解成更小的部分呢?
在這種情況下,我們可以將2個項目放入每個組,然后剩下3個額外的項目放入一個組:
這被稱為余數(shù)。這是模運算符產(chǎn)生的結(jié)果。
在這些數(shù)字可以被平均分為幾組的情況下(例如,12 ÷ 4),沒有余數(shù):
12 % 4; // 0
在被除數(shù)(要被除的數(shù))不能平均分成幾組的情況下,模運算符讓我們知道還剩多少:
11 % 4; // 3
一個真實的使用案例
我不是一個數(shù)學(xué)家,我是一個Web開發(fā)人員。所有這些數(shù)學(xué)內(nèi)容都很有趣,接下來讓我們談?wù)勀_\算符如何在前端頁面上派上用場。
具體來說,有一種問題我似乎經(jīng)常遇到,模運算符提供了完美的解決方案:循環(huán)數(shù)組。
假設(shè)我們有一個三種顏色的數(shù)組。每一秒都想切換到列表中的下一個顏色。當(dāng)我們到達列表的末尾時,我們就繼續(xù)回到第一項:
這是一個比較棘手的問題。假設(shè)我們有一個名為timeElapsed
的變量,它從0開始,每秒遞增1。我們必須以某種方式將這個不斷增加的值最終映射到一個只有3項的數(shù)組。
基于以上我們可以編寫一個函數(shù),它會產(chǎn)生以下結(jié)果:
const COLORS = ['red', 'yellow', 'blue']; getColor({ timeElapsed: 0 }); // 'red' getColor({ timeElapsed: 1 }); // 'yellow' getColor({ timeElapsed: 2 }); // 'blue' getColor({ timeElapsed: 3 }); // 'red' getColor({ timeElapsed: 4 }); // 'yellow' getColor({ timeElapsed: 5 }); // 'blue' getColor({ timeElapsed: 6 }); // 'red' getColor({ timeElapsed: 7 }); // 'yellow' getColor({ timeElapsed: 8 }); // 'blue'
讓我們看看模運算符如何幫助我們解決這個問題:
const COLORS = ['red', 'yellow', 'blue']; function getColor({ timeElapsed }) { const colorIndex = timeElapsed % COLORS.length; return COLORS[colorIndex]; }
奇跡般地這正是我們所需要的結(jié)果!只要timeElapsed
是一個整數(shù),這個方法總是返回三種顏色中的一種。它會隨著timeElapsed
的增加而循環(huán)通過3種顏色。
COLORS.length
等于3,因為我們的數(shù)組中有3種顏色。因此隨著timeElapsed
從0遞增到8,該函數(shù)最終執(zhí)行以下計算序列:
const colorIndex = 0 % 3; // 0 const colorIndex = 1 % 3; // 1 const colorIndex = 2 % 3; // 2 const colorIndex = 3 % 3; // 0 const colorIndex = 4 % 3; // 1 const colorIndex = 5 % 3; // 2 const colorIndex = 6 % 3; // 0 const colorIndex = 7 % 3; // 1 const colorIndex = 8 % 3; // 2
然后我們可以使用這個colorIndex
從COLORS
數(shù)組中查找顏色。它保證總是在該數(shù)組的可用索引范圍內(nèi)循環(huán)。
要理解為什么這樣做,值得記住我們的新除法模型:我們試圖將timeElapsed
分成3個大小相等的組,沒有任何分數(shù)或小數(shù)值。余數(shù)總是0、1或2。它永遠不會是3+,因為如果還有3個,我們可以在每組中再放1個!
從本質(zhì)上講,這就好像我們有能力創(chuàng)建一個“圓形”數(shù)組。無論底層的timeElapsed
值增長到多大,我們都可以讓它在COLORS
數(shù)組中無限循環(huán)。
在我看來,僅憑這個小技巧,模運算符就值得學(xué)習(xí)!這些年來,我已經(jīng)多次使用這種循環(huán)數(shù)組技巧,這只是模運算符的幾個實際用例之一。
最后
本文通過改進除法的心理模型來學(xué)習(xí)模運算是如何工作的,并介紹了一個很實用的日常實踐,希望對你有所幫助。
更多關(guān)于JavaScript模運算符的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrap fileinput.js文件上傳組件實例代碼
這篇文章主要介紹了BootStrap fileinput.js文件上傳組件實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02javascript 如何生成不重復(fù)的隨機數(shù)
javascript 如何生成不重復(fù)的隨機數(shù)...2007-11-11JavaScript實現(xiàn)圖片放大預(yù)覽效果
這篇文章主要介紹了JavaScript實現(xiàn)圖片放大預(yù)覽效果,幫助大家更好的理解和制作JavaScript特效,感興趣的朋友可以了解下2020-11-11關(guān)于__defineGetter__ 和__defineSetter__的說明
關(guān)于__defineGetter__ 和__defineSetter__的說明...2007-05-05JS腳本根據(jù)手機瀏覽器類型跳轉(zhuǎn)WAP手機網(wǎng)站(兩種方式)
隨著移動互聯(lián)網(wǎng)的不斷普及,企業(yè)的網(wǎng)絡(luò)宣傳不僅只局限在PC端,還要在移動端發(fā)展。我們在自己的網(wǎng)站做了WAP手機完整之后,如果有用戶通過手機訪問我們的企業(yè)頂級域名網(wǎng)站,就要判斷跳轉(zhuǎn)到專為的WAP網(wǎng)站,下面小編給大家整理有關(guān)手機瀏覽器跳轉(zhuǎn)WAP手機網(wǎng)站的相關(guān)內(nèi)容2015-08-08