内置的JavaScript Math对象包含许多有用的函数,用于执行各种数学运算。让我们深入了解它们的工作原理以及你可能要使用它们做什么。
Math.max and Math.min
这些函数基本上做你所期望的事情:它们返回提供的参数列表中的最大值或最小值:
Math.max(1,2,3,4,5)
<< 5
Math.min(4,71,-7,2,1,0)
<< -7
所有参数都必须是Number数据类型,否则将返回NaN:
Math.max('a','b','c')
<< NaN
Math.min(5,"hello",6)
<< NaN
但要注意,JavaScript将尝试将值强制转换为数字:
Math.min(5,true,6)
<< 1
在这个例子中,布尔值true被强制转换为数字1,这就是为什么它被返回为最小值的原因。如果你不熟悉类型转换,它发生在运算符的操作数是不同类型时。在这种情况下,JavaScript将尝试将一个操作数转换为另一个操作数类型的等效值。你可以在《JavaScript高级程序设计》第三版第三章中阅读更多关于JavaScript中的类型转换的内容。
需要将一组数字作为参数提供,而不是一个数组,但你可以使用展开运算符(...)来解包一个数字数组:
Math.max(...[8,4,2,1])
<< 8
Math.max函数对于从保存在数组中的分数列表中找到最高分非常有用:
const scores = [23,12,52,6,25,38,19,37,76,54,24]
const highScore = Math.max(...scores)
<< 76
Math.min函数对于在价格比较网站上找到最佳价格非常有用:
const prices = [19.99, 20.25, 18.57, 19,75, 25, 22.50]
const bestPrice = Math.min(...prices)
<< 18.57
Absolute Values
绝对值是指一个数的大小,无论它的大小如何。这意味着正数保持不变,而负数将失去其负号。Math.abs函数将计算它的参数的绝对值:
Math.abs(5)
<< 5
Math.abs(-42)
<< 42
Math.abs(-3.14159)
<< 3.14159
为什么要这样做呢?有时候你想计算两个值之间的差,这可以通过从最大值中减去最小值来计算,但通常你事先不知道哪个值是这两个值中的最小值。为了解决这个问题,你可以以任何顺序减去数字并取绝对值:
const x = 5
const y = 8
const difference = Math.abs(x - y)
<< 3
一个实际的例子可能出现在一个省钱的网站上,你想通过计算两个优惠之间的差异来知道你可以节省多少钱,因为你正在处理实时的价格数据,并且不知道哪个优惠是最便宜的:
const dealA = 150
const dealB = 167
const saving = Math.abs(dealA - dealB)
<< 17
Math.pow
Math.pow执行幂计算,例如:
3⁴ = 81
在上面的例子中,3被称为底数,4被称为指数。我们可以将其阅读为“3的4次幂是81”。
该函数接受两个值——底数和指数——并返回将底数乘以指数次幂的结果:
Math.pow(2,3)
<< 8
Math.pow(8,0)
<< 1
Math.pow(-1,-1)
<< -1
Math.pow函数已经被中缀指数运算符(**)所取代——自ES2016引入——它执行完全相同的操作:
2 ** 3
<< 8
8 ** 0
<< 1
(-1) ** (-1)
<< -1
Calculating Roots
根是幂的反向操作。例如,由于3的平方是9,因此9的平方根是3。
Math.sqrt可以用于返回作为参数提供的数字的平方根:
Math.sqrt(4)
<< 2
Math.sqrt(100)
<< 10
Math.sqrt(2)
<< 1.4142135623730951
如果提供的参数是负数或非数字值,则此函数将返回NaN:
Math.sqrt(-1)
<< NaN
Math.sqrt("four")
<< NaN
但要注意,因为JavaScript会尝试强制转换类型:
Math.sqrt('4')
<< 2
Math.sqrt(true)
<< 1
Math.cbrt返回一个数字的立方根。它接受所有数字——包括负数。它还会尝试强制转换类型,如果使用的值不是数字,则会尝试将其强制转换为数字。如果无法将该值转换为数字,则会返回NaN:
Math.cbrt(1000)
<< 10
Math.cbrt(-1000)
<< -10
Math.cbrt("10")
<< 2.154434690031884
Math.cbrt(false)
<< 0
可以使用指数运算符和分数幂来计算其他根。例如,可以通过将数字提高到四分之一的幂(或0.25)来找到其四次方根。因此,以下代码将返回625的四次方根:
625 ** 0.25
<< 5
要找到一个数字的五次方根,可以将其提高到五分之一的幂(或0.2):
32 ** 0.2
<< 2
一般来说,要找到一个数字的n次方根,可以将其提高到1/n的幂,因此要找到一百万的六次方根,可以将其提高到1/6的幂:
1000000 ** (1/6)
<< 9.999999999999998
请注意,这里存在舍入误差,因为答案应该是精确地10。这通常会发生在无法在二进制中精确表示的分数幂次计算中。 (您可以在“JavaScript中舍入数字的指南”中阅读更多关于这个舍入问题的内容。)
另请注意,如果根为偶数,则无法找到负数的根。这将返回NaN。因此,您不能尝试找到-7的10次方根(因为10是偶数)。
(-7) ** 0.1 // 0.1 is 1/10
<< NaN
一个你需要计算根的原因是为了计算增长率。例如,假设你想在今年年底时使利润增加10倍。你的利润每个月需要增长多少?要找出这个答案,你需要计算10的12次方的12次根:
10 ** (1/12)
<< 1.2115276586285884
这个结果告诉我们,为了在年底使利润增加10倍,每月的增长因子必须约为1.21。或者换句话说,您需要每个月将利润增加21%才能实现目标。
对数和指数
对数(或简称为“log”)可以用来找到计算的指数。例如,假设您想要解决以下方程:
2ˣ = 100
在上面的方程中,x肯定不是整数,因为100不是2的幂。这可以通过使用以2为底的对数来解决:
x = log²(100) = 6.64 (rounded to 2 d.p.)
是的,Math对象有一个log2方法,它将执行此计算:
Math.log2(100)
<< 6.643856189774724
它还有一个log10方法执行相同的计算,但使用10作为基数:
Math.log10(100)
<< 2
Math.log方法是另一个log方法,它计算自然对数,使用欧拉数e(约为2.7)作为底数。这可能似乎是使用奇怪的值,但实际上在自然界中经常出现指数增长——因此被称为“自然对数”:
Math.log(10)
<< 4.605170185988092
Math.log(Math.E)
<< 1
最后一个计算表明,自然对数的底数——欧拉数(e)——存储为常量Math.E,需要将其提升为1次幂以获得自己。这是有道理的,因为任何数的1次幂实际上都是本身。如果将2和10提供为Math.log2和Math.log10的参数,可以获得相同的结果:
Math.log2(2)
<< 1
Math.log10(10)
<< 1
为什么要使用对数?当处理呈指数增长的数据时,常常使用对数比例尺以便更容易看出增长速度。在疫情期间,经常使用对数比例尺来测量每天COVID-19病例数量,因为病例数量上涨得非常快。
如果您很幸运,拥有一个网站的流行度在迅速增长(比如每天翻倍),那么在显示图表以展示您的流行度增长情况时,您可能需要考虑使用对数比例尺。
直角三角形的斜边
你可能还记得在学校学习毕达哥拉斯定理。它指出,一个直角三角形的斜边(也就是最长的一条边,即“斜边”)的长度可以用以下公式求出:
h² = x² + y²
在这里,x和y是另外两条边的长度。
Math对象有一个hypot方法,当提供其他两条边的长度作为参数时,它将计算斜边的长度。例如,如果一边长度为3,另一边长度为4,我们可以使用以下代码计算斜边的长度:
Math.hypot(3,4)
<< 5
但这有什么用呢?嗯,直角三角形的斜边长度可以测量两点之间的最短距离。这意味着,如果您知道页面上两个元素的 x 和 y 坐标,则可以使用这个函数计算它们之间的距离:
const ship = {x: 220, y: 100}
const boat = {x: 340, y: 50}
const distance = Math.hypot(ship.x - boat.x,ship.y - boat.y)
希望这篇文章对您有所帮助,帮助您在项目中充分利用 JavaScript Math 对象的全部功能。