当我第一次学习编码时,我记得发现模运算符(%)非常令人困惑。当你不明白它的原理的时候,它产生的值看起来完全是随机的:
const what = 10 % 4; // 2
const the = 10 % 10; // 0
const heck = 4 % 10; // 4
在这篇文章中,我们将通过改进除法的心理模型来学习这个运算符是如何工作的,文末还将介绍一个实用的日常实践。
受众群体:
这篇博客文章是为初级到中级JavaScript开发人员所写。一些JavaScript知识是假设的,但核心内容应该对每个人都有用!
假设我们有下面的计算:
12 ÷ 4
除法常常让人感觉非常抽象或理论化,但有一种实用的方法来思考它:我们可以把一个数字分成大小相等的组。
12 ÷ 4的计算结果为3,因为每个组正好包含3个项目。从本质上讲我们正在计算每个组中将包含多少个项目。
在上面的示例中我们的被除数是12。使用除法时,它可以用很多不同的方式来分割。
假设我们有以下等式:
11 ÷ 4
这个方程式的值为2.75。每组有2个完整的项目,然后是另一个项目的3/4。
如果我们分披萨或蛋糕,这是可行的。但如果这些物品是不可摧毁的呢?如果我们不能把每一项分解成更小的部分呢?
在这种情况下,我们可以将2个项目放入每个组,然后剩下3个额外的项目放入一个组:
这被称为余数。这是模运算符产生的结果。
在这些数字可以被平均分为几组的情况下(例如,12 ÷ 4),没有余数:
12 % 4; // 0
在被除数(要被除的数)不能平均分成几组的情况下,模运算符让我们知道还剩多少:
11 % 4; // 3
我不是一个数学家,我是一个Web开发人员。所有这些数学内容都很有趣,接下来让我们谈谈模运算符如何在前端页面上派上用场。
具体来说,有一种问题我似乎经常遇到,模运算符提供了完美的解决方案:循环数组。
假设我们有一个三种颜色的数组。每一秒都想切换到列表中的下一个颜色。当我们到达列表的末尾时,我们就继续回到第一项:
这是一个比较棘手的问题。假设我们有一个名为timeElapsed的变量,它从0开始,每秒递增1。我们必须以某种方式将这个不断增加的值最终映射到一个只有3项的数组。
基于以上我们可以编写一个函数,它会产生以下结果:
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];
}
奇迹般地这正是我们所需要的结果!只要timeElapsed是一个整数,这个方法总是返回三种颜色中的一种。它会随着timeElapsed的增加而循环通过3种颜色。
COLORS.length等于3,因为我们的数组中有3种颜色。因此随着timeElapsed从0递增到8,该函数最终执行以下计算序列:
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数组中查找颜色。它保证总是在该数组的可用索引范围内循环。
要理解为什么这样做,值得记住我们的新除法模型:我们试图将timeElapsed分成3个大小相等的组,没有任何分数或小数值。余数总是0、1或2。它永远不会是3+,因为如果还有3个,我们可以在每组中再放1个!
从本质上讲,这就好像我们有能力创建一个“圆形”数组。无论底层的timeElapsed值增长到多大,我们都可以让它在COLORS数组中无限循环。
在我看来,仅凭这个小技巧,模运算符就值得学习!这些年来,我已经多次使用这种循环数组技巧,这只是模运算符的几个实际用例之一。
本文通过改进除法的心理模型来学习模运算是如何工作的,并介绍了一个很实用的日常实践,希望对你有所帮助。
本文翻译自 Understanding the JavaScript Modulo Operator,作者:joshwcomeau
我们都知道通过Math.floor()方法可实现数值的向下取整,得到小于或等于该数字的最大整数。除了Math.floor方法,还可以使用位运算|,>>来实现向下取整哦
扩展运算符( spread )是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。
位运算的方法在其它语言也是一样的,不局限于JS,所以本文提到的位运算也适用于其它语言。位运算是低级的运算操作,所以速度往往也是最快的
平常的数值运算,其本质都是先转换成二进制再进行运算的,而位运算是直接进行二进制运算,所以原则上位运算的执行效率是比较高的,由于位运算的博大精深,下面通过一些在js中使用位运算的实例
js实现:四舍五入、向上取整、向下取整等方法。parseInt、Math.ceil、Math.round、Math.floor、toFixed等的使用
JS经常会遇到延迟执行的动作,并且失败后自动尝试,尝试N次之后就不再尝试的需求,今天刚好又遇到,于是写个闭包,以后不断完善继续复用。检查并计数第一个参数用来标记是尝试哪个动作的,第二个参数是最大尝试次数
大多数语言都提供了按位运算符,恰当的使用按位运算符有时候会取得的很好的效果。在我看来按位运算符应该有7个:& 按位与、| 按位或、^ 按位异或、~ 按位非
PHP取整数函数常用的四种方法:1.直接取整,舍弃小数,保留整数:intval(); 2.四舍五入取整:round(); 3.向上取整,有小数就加1:ceil(); 4.向下取整:floor()。
ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true。相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性。
前端工作中经常遇到数字计算保留小数问题,由于不是四舍五入的方式不能使用toFixed函数,本文采用正则表达式匹配字符串的方式,解决对数字的向上或向下保留小数问题:
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!