本文共 10238 字,大约阅读时间需要 34 分钟。
Write By Monkeyfly
以下内容均为原创,如需转载请注明出处。
Math
对象的属性Math
对象的方法Math对象与其他对象不一样,它不需要使用new关键字来创建,用法简单粗暴。直接使用Math.属性/方法
即可。
按照官方的说法就是: Math对象无需在使用这个对象之前对它进行定义。
Math(数学)对象的作用是:执行普通的算数任务。
语法:
Math.属性Math.方法
JavaScript
提供了 8
种可被Math
对象访问的属性(算数值)。
说明:
(1)在这里,我们只需要掌握“Math.PI”
这一个属性就足够了。PI
就代表圆周率。
“弧度”
为单位。 例如:
180°
应该这样写成Math.PI
,而360°
应该写成Math.PI*2
,以此类推。 注意:
对于角度,在实际开发中,推荐这种写法:度数 * Math.PI/180
【公式为什么这样写?原因在下面。】 原因:
因为这种写法能让我们一眼就能看出角度是多少。角度转换弧度的数学公式:角度×(π/180)
要知道原因,我们首先要知道什么是弧度(制)?
与半径等长的圆弧所对应的圆心角叫做1弧度
的角,用符号rad
表示。如下图示:
然后我们又知道,圆的周长公式为2πr
,所以一个圆周的弧长为2πr
。
所以,根据上面的,我们可以得到:
弧长所对应的圆周角 | 弧长 |
---|---|
1rad 的角 | 弧长 = 半径 = r |
2π rad 的角 | 弧长 = 圆的周长 = 2πr |
注意:角度以弧度给出时,通常不写弧度单位rad
。
换算:
前提:我们都知道,在角度制中,我们把周角的1/360
看作1°
,所以圆的一周就是360°
。 一个完整的圆的弧度是2π,所以:2π rad = 360°,1π rad = 180°,1°=π/180° rad ,1 rad = (180/π)°≈57.30°=57°18ˊ。
由此可以得出:n° = n * (π/180°)。
因此,角度转换弧度的数学公式为:角度×(π/180)
举例:
120 * Math.PI/180 //120°150 * Math.PI/180 //150°document.write("" + "圆周率为:" + Math.PI + "");//圆周率为:3.141592653589793
分析:
在实际开发中,对于圆周率(π)
,正确的写法是使用Math.PI
来表示。【一定要记住】
常用的方法如下:
方法 | 说明 |
---|---|
max(a,b,…n) | 返回一组数中的最大值 |
min(a,b,…n) | 返回一组数中的最小值 |
sin(x) | 正弦 |
cos(x) | 余弦 |
tan(x) | 正切 |
asin(x) | 反正弦 |
acin(x) | 反余弦 |
atan(x) | 反正切 |
atan2(x) | 反正切 |
floor(x) | 向下取整 |
ceil(x) | 向上取整 |
round(x) | 四舍五入 |
random(x) | 生成随机数 |
不常用的方法:
方法 | 说明 |
---|---|
abs(x) | 返回x的绝对值 |
sqrt(x) | 返回x的平方根 |
log(x) | 返回x的自然对数(以e为底) |
pow(x,y) | 返回x的y次幂 |
exp(x) | 返回e指数 |
我们可以使用max()
方法求出一组数中的最大值,用min()
方法可以求出一组数中的最小值。
语法:
Math.max(a,b,c,...,n);Math.min(a,b,c,...,n);
举例:
var a = Math.max(4,8,0,99,66,78);var b = Math.min(4,8,0,99,66,78);document.write("最大值为:" + a + "");//最大值为:99document.write("最小值为:" + b + "");//最小值为:0
分析:
有了这两个方法,以后求最大最小值就方便多了。再也不用冒泡排序了。方法 | 说明 |
---|---|
sin(x) | 正弦 |
cos(x) | 余弦 |
tan(x) | 正切 |
asin(x) | 反正弦 |
acin(x) | 反余弦 |
atan(x) | 反正切 |
atan2(x) | 反正切 |
说明:
(1)x
表示角度值,用弧度来表示,常用形式:度数 * Math.PI/180
(2)atan2(x)
不同于atan(x)
。atan2(x)
能够判断角度对应哪一个角,而atan(x)
不能。 因此,在高级动画开发时,我们大多数用的是atan2(x)
,基本用不到atan(x)
。 (3)反三角函数用的很少(但atan2(x)
除外),一般都是使用三角函数。 (4)常用的三角函数有:sin(x)、cos(x)、atan2(x)
。 (5)这些三角函数是高级动画开发的基础。 举例:
document.write("" + "sin30°:" + Math.sin(30 * Math.PI / 180) + "");//0.49999999999999994document.write("" + "cos60°:" + Math.cos(60 * Math.PI / 180) + "");//0.5000000000000001document.write("" + "tan45°:" + Math.tan(45 * Math.PI / 180) + "");//0.9999999999999999
问题:为什么sin30°不等于0.5呢?还有其他的值也和预想的不一样。
分析:
这是因为JavaScript计算精度的问题,存在一定的误差,我门可以忽略不计。知道就行了。
floor()
对一个数进行向下取整,即返回≤ 指定数(x)的最小整数
。
语法:
Math.floor(x)
如:floor(3.3)
就会返回3
。它相当于四舍五入中的“舍”,不管在任何情况都会舍去,取最小值。即使是floor(3.9)
也会返回3
。
举例:
document.write("" + "Math.floor(3.5):" + Math.floor(3.5) + "");//3document.write("" + "Math.floor(0.4):" + Math.floor(0.4) + "");//0document.write("" + "Math.floor(0):" + Math.floor(0) + "");//0document.write("" + "Math.floor(-1.1):" + Math.floor(-1.1) + "");//-2document.write("" + "Math.floor(-1.9):" + Math.floor(-1.9) + "");//-2
分析:
由上可知, (1)对于正整数而言:如果x
为整数,则返回x
本身;如果x
为小数,则返回小数点之前的整数
。 (2)对于负整数而言:如果-x
为整数,则返回-x
本身;如果-x
为小数,则返回小数点之前的整数位+1的整数
。 ceil()
对一个数进行向上取整,即返回≥ 指定数(x)的最小整数
。
语法:
Math.ceil(x)
如:ceil(3.6)
就会返回4
。它相当于四舍五入中的“入”,不管在任何情况都会进位,取最接近的整数值。即使是ceil(3.1)
也会返回4
。
举例:
document.write("" + "Math.ceil(3.5):" + Math.ceil(3.5) + "");//4document.write("" + "Math.ceil(0.4):" + Math.ceil(0.4) + "");//1document.write("" + "Math.ceil(0):" + Math.ceil(0) + "");//0document.write("" + "Math.ceil(-1.1):" + Math.ceil(-1.1) + "");//-1document.write("" + "Math.ceil(-1.9):" + Math.ceil(-1.9) + "");//-1
分析:
由上可知,
(1)对于正整数而言:如果x
为整数,则返回x
本身;如果x
为小数,则返回小数点之前的整数位+1的整数
。 (2)对于负整数而言:如果-x
为整数,则返回-x
本身;如果-x
为小数,则返回小数点之前的整数
。 round()
方法可把一个数字舍或者入为最接近的整数。它是根据数字自动进行舍入的。
简单来说就是,把一个数四舍五入为最接近的整数。
语法: Math.round(x)
说明:
对于0.5
,该方法将进行上舍入。 例如,3.5
将舍入为4
,而 -3.5
将舍入为-3
。 举例:
document.write( Math.round(0.60) + "");//1document.write( Math.round(0.50) + "");//1document.write( Math.round(0.49) + "");//0document.write( Math.round(-4.40) + "");//-4document.write( Math.round(-4.60) + "");//-5
分析:
简单来说就是:被舍部分的头一位数满五加一,不满五的就舍去。 关于四舍五入,大家都明白,这里就不再赘述。在JavaScript
中,我们可以使用random()
方法来生成一个0~1
之间的一个随机数。
random
就是“随机”
的意思。
说明:人家规定,这里的0~1
为[0,1)
,即只包含0
,不包含1
,前闭后开。
虽然我自己在控制台试了十几次Math.random()
也没有得到所谓的0
,但是不管它了,反正是人家的规定,记住这个原则就可以了,不必去深究。
看图说话:
语法: Math.random()
说明:
(1)随机数在开发中是非常有用的,随处可见。 (2)Math.random()
等价于Math.random()*1+0
,相当于省略掉了。【看书总结的,也不知道对不对】 (3) Math.random()*1+0
应该是它的原型,个人觉得记这个比较好,方便使用。【如果有错误,欢迎指正】 (4)我们可以发现,random()
方法默认生成随机数的区间为[0,1)
,刚好对应 Math.random()*1+0
中的0
和1
, 即开(右)区间的数字在前,闭(左)区间的数字在后,相当于大数在前,小数在后。 (5)我们也可以发现,在 Math.random()*1+0
中,操作符*
在前,+
在后,我们可以这样记忆:前乘后加(或先乘后加)。 因此,我们可以这样去记忆:
random()
方法中生成随机数的区间,开区间的数字在前,闭区间的数字在后。random()
方法中,操作符*
在前,+
在后。注意:
这只是我自定义的原则。(其实,这种叫法是不存在的,纯粹是我自己为了方便记忆才这么命名的)比如说:你要使用random()
方法生成0~3
之间的随机数,即[0,3)
,就可以这样写:
1、首先根据“前开后闭”
原则,定好区间数字在random()
方法中的位置。即3在前,0在后
。我们会得到:Math.random() 3 0
。
先乘后加
原则,给固定好位置的区间数字添加相应的操作符。即*在前,+在后
。我们会得到:Math.random()*3 +0
。 3、大功告成,这样就写完了。 比如说:你要使用random()
方法生成-3~3
之间的随机数,即[-3,3)
,就可以这样写:
1、首先根据“前开后闭”
原则,定好区间数字在random()
方法中的位置。即3在前,-3在后
。我们会得到:Math.random() 3 -3
。
先乘后加
原则,给固定好位置的区间数字添加相应的操作符。即*在前,+在后
。我们会得到:Math.random()*3 +(-3)
。 3、大功告成,这样就写完了。 4、运行后发现,得到的并不是自己想要的随机数;然后多试几次发现,生成随机数的区间是在[-3,0)
之内的。 如下图所示:
认真分析一番发现:
-3
与3
进行了相加运算,它们运算后的结果0
作为了生成随机数的右(开)区间,即[ -3,3+(-3) )
,于是最终为[-3,0)
。0
了,而是-3
。之前生成随机数的区间是[0,-3)
,而现在是[-3,3)
。对于数字0
来说,参不参加运算作用都是一样,对生成随机数的结果并没有什么影响。但是对于除0
以外的其他数字而言,比如说-3
,从实际操作中我们可以看出来:它是需要参加运算的,所以最终得到的随机数结果与之前总结的规律不符。Math.random()*3 +(-3)
生成的随机数范围不是[-3,3)
的,而是[ -3,3+(-3) )
,即[-3,0)
。5、所以,要生成-3~3
之间的随机数应该这样写才对:Math.random()*6 +(-3)
,即[ -3,6+(-3) )
=>[3-,3)
。
通过这两个例子,我们可以发现:
我之前总结的“前开后闭”原则描述不准确,现在必须要进行修改:
“后闭”
的说法是没有问题的,目前需要改的是“前开”
。闭区间的数字(即小数字)依然放置在+
后面这个固定不变;而之前所谓的“前开”原则是有问题的
,即右(开)区间的数字在前,位于*
后面,实际论证后并不可取。所以,从现在起就不要再去使用“前开”原则了
。
因为对于区间来说,一般都是小数在前,大数在后。所以小数
在random()
方法中的位置固定不变,依然是后置
,位于+
后面,即Math.random()*? +(-3)
。
而右(开)区间的数字(即大数
),它是由某个数与
左(闭)区间的数字(即小数
)经过相加得到的
。不仅仅是简单的区间数字“对号入座”。
这里的某个数
指的就是random()
方法中*
后面的数字。
现在,我们知道了:
如果我们想要使用 Math.random()方法 得到指定区间的随机数,应该这么做:( 默认获得的随机数是这样的[x,y) )
注:Math.random()方法 的等价形式:Math.random()*1 +0,它对应的随机数区间为[0,1)
一般来说,要生成的随机数区间中的数字,我们是已知的,所以我们就需要将这两个数字以某种方式放入Math.random()
方法中。
在这里,我们假设要生成x
到y
之间的随机数,即[x,y)
。那么,在Math.random()
方法中该如何去写呢?
Math.random() * ? + ?
random()
方法中的第二个数字
,即 +
号后面的数字。它的值是确定的。
x
。所以,在这里,我们将数字 x
填入 Math.random()
方法中Math.random() * ? + x
再说random()
方法中的第一个数字
,即*
号后面的数字,我们假设该数字为z
,且它的值是不确定的。
y
。它只是决定了随机数区间中大数字y
的值。如果我们想要得到随机数区间中大数字y的值,那么必须要通过random()方法中的两个数字的相加运算得到。
即y = z + x
// z + x = y 所要生成的随机数区间为:[x,y) 且 x < yMath.random() * z + x
[x,y)
,在Math.random()
方法中,对于第二个数字而言,可以直接在 +
后面直接填充 随机数区间中的小数字x
,然后将随机数区间中大数字与小数字的差(即y-x
的值)作为第一个数字,填充至 *
后面。总结:
random()
方法中,*
号在前,+
号在后。即 Math.random()*? +?
。random()
方法中的+
后面。即 Math.random()* +(-3)
。random()
方法中,*
号后面的数字是由区间中的大数 - 小数
得到的。即它是由右(开)区间的数字-
左(闭)区间的数字得到的。即? = 3 - (-3)
,得到? = 6
,所以最终得到Math.random()*6 +(-3)
,即Math.random()*6 -3
。(或者说后减前原则)所以,如果我们要得到所生成的随机数区间中开区间的大数字
,可以这样算:
random()方法中 *号 后面的数字(第一个数字) + 随机数区间中的小数字 = 随机数区间中的大数字
那么,反过来,如果我们要得到random()方法中的第一个数字
,也可以这样算:(因为第二个数字是固定的,即随机数区间中的小数字)
random()方法中 *号 后面的数字(第一个数字) = 随机数区间中的大数字 - 随机数区间中的小数字
比如说:你要使用random()
方法生成-3~3
之间的随机数,即[-3,3)
,就可以这样写:Math.random()*6 +(-3)
举例:
/*Math.random()方法的原型为:Math.random()*1 +0*/document.write("" + "生成[0,1)之间的随机数:" + Math.random() + "");//Math.random()*1 +0document.write("" + "生成[0,5)之间的随机数:" + Math.random()*5 + "");//Math.random()*5 +0document.write("" + "生成[5,15)之间的随机数:" + (Math.random()*10+5) + "");//Math.random()*10 +5document.write("" + "生成[-5,5)之间的随机数:" + (Math.random()*10-5) + "");//Math.random()*10 -5document.write("" + "生成[-10,10)之间的随机数:" + (Math.random()*20-10) + "");//Math.random()*20 -10
【随机数的使用技巧】
技巧1:随机生成某个范围内的“任意数”(包括整数和小数)
1.Math.random()*m //[0,m),这里的 m 相当于 m+0
表示生成0~m
之间的随机数。
例如:Math.random()*10
表示生成0~10
之间的随机数。
2.Math.random()*m+n //[n,m+n)
表示生成n~m+n
之间的随机数。
例如:Math.random()*10+8
表示生成8~18
之间的随机数。
3.Math.random()*m-n //[-n,m-n),这里的 m-n 相当于 m+(-n)
表示生成-n~m-n
之间的随机数。
例如:Math.random()*10-8
表示生成-8~2
之间的随机数。
4.Math.random()*2m-m //[-m,m),这里的 m 相当于 2m-m
表示生成-m~m
之间的随机数。
例如:Math.random()*20-10
表示生成-10~10
之间的随机数。
5.Math.random()*m-m //[-m,0),这里的 0 相当于 m-m
表示生成-m~0
之间的随机数。
例如:Math.random()*10-10
表示生成-10~0
之间的随机数。
技巧2:随机生成某个范围内的“整数”
在这里,我们利用前面学到的floor()向下取整
方法 和ceil()向上取整
方法。
对于Math.random()*5
来说,表示生成0~5
之间的随机数(包括整数和小数),即[0,5)
。
注意:
[0,5)
,而不是[0,5]
。前面说过了,人家规定好的语法,记住就行。floor()向下取整
方法、ceil()向上取整
方法 或者parseInt()
方法,改变默认生成的随机数区间。floor()
方法 与 parseInt()
方法 取整的功能类似,都是向下取整。~
表示生成的随机数区间 中的开区间
,使用-
表示生成的随机数区间 中的闭区间
。(只是为了便于分别生成的随机数和随机整数)说明:
floor()
方法向下取整,那么Math.floor( Math.random()*5 )
生成的就是0-4
之间的随机整数,即[0,4]
。ceil()
方法向上取整,那么Math.ceil( Math.random()*5 )
生成的就是0-5
之间的随机整数,即[0,5]
。Q&A:
问:如果想生成0-5之间
的随机整数应该怎么写呢?【*5 +0 指 0~5
,那*(5+1) +0 指 0~(5+1)
,向下取整后为0-5
】
Math.floor( Math.random()*(5+1) );
原因:因为floor()
向下取整,所以右区间必须+1
,相当于开区间的[0,5+1)
变为了闭区间的[0,5]
。 问:如果想生成0到任意数之间
的随机整数应该怎么写呢?【*m +0 指 0~m
,那*(m+1) +0 指 0~(m+1)
,向下取整后为0-m
】
5
改为m
即可,Math.floor( Math.random()*(m+1) );
问:如果想生成1到任意数之间
的随机整数应该怎么写呢?【*m +n 指 n~(m+n)
,那*m +1 指 1~(m+1)
,向下取整后为1-m
】
Math.floor( Math.random()*(m+1) + 1);
原因1:Math.random()
等价于Math.random()*1+0
,这相当于它的原型,表示取得的随机数范围是[0,1)
。 原因2:因为floor()
向下取整,所以Math.floor( Math.random()*1 +0 )
表示[0,0]
,即0
。 因此,我们可以得出:
1.Math.random() => Math.random()*1 +0 //表示生成0~1之间的随机数,左闭右开,即[0,1) 2.那么,Math.floor(Math.random()*1 +0); //向下取整后得到的结果为[0,0],也就是得到的值恒为整数03.若要得到0到任意数之间的随机整数,即[0,0+m],应该在上面的基础上这样写:Math.floor(Math.random()*(1+m) +0);4.那要得到`1到任意数之间`的随机整数呢?应该在上面的基础上这样写:Math.floor( Math.random()*(1+m) + (0+1) );5.化简后,即:Math.floor( Math.random()*(m+1) + 1) //两个区间都必须+1,相当于[0+1,1+m]。
问:如果想生成任意数到任意数之间
的随机整数应该怎么写呢?【*m+n指n~m+n
,那*m-n+1 +n指n~(m-n+1)+n
,即n~m+1
,向下取整后为n-m
】
Math.floor( Math.random()*(m-n+1) + n);
注意:
parseInt( Math.random()*5); //生成的 0-4 之间的随机数,即区间 [0,4]。 Math.floor( Math.random()*5 ); //生成的 0-4 之间的随机数,即区间 [0,4]。 Math.ceil( Math.random()*5 ); //则是生成的 1-5 之间的随机数,即区间 [1,5]。
分析: (1)parseInt()
和Math.floor()
这两个方法的作用是一样的,都是向下取整。 (2)但是,parseInt()
这个方法主要是用来解析一个字符串参数,并返回一个指定基数(即多少进制)的整数。 (3)语法:parseInt(string, radix);
,不指定第二个参数的话,默认是以10进制为基数进行解析的。