JavaScript 基础
Document
运算符
深入数据和类型
函数进阶
原型、继承
类
浏览器存储
Web API
事件
错误处理
异步编程
网络请求
模块
练习
实例
工具与规范
软件架构模式
设计模式
本章是数字类型的进阶讲解,有关数字类型的初步介绍请看 Number类型章节。
数字的编写
下划线
数字中的下划线会被忽略,这有助于我们书写数字的正确性。比如西方常用的千位分割符就可以用下划线替代。
$$jsdemo$$
$$edit$$
let n = 1000000 // 一百万
let n2 = 1_000_000 // 一百万,用 _ 代替千位分隔符
alert(n) // 1000000
alert(n2) // 1000000
alert(n === n2) // true
科学记数法
数值的表示中也可以使用科学记数法, e
代表 10 的幂。
$$jsdemo$$
$$edit$$
let n = 10000 // 一万
let n2 = 1e4 // 一万,用科学计数法
alert(n) // 10000
alert(n2) // 10000
alert(n === n2) // true
let n3 = 0.012 // 0.012
let n4 = 12e-3 // 0.012,用科学计数法
alert(n3) // 0.012
alert(n4) // 0.012
alert(n3 === n4) // true
进制
默认的数字是十进制 ,意味着逢十进一,每位上取值是 0 ~ 9
。除此之外常用的还有十六进制、八进制、二进制。
- 十六进制:逢十六进一,每位上取值是
0 ~ f
。 - 八进制:逢八进一,每位上取值是
0 ~ 7
。 - 二进制:逢二进一,每位上取值是
0 ~ 1
。
$$tip
$$
$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255
let n2 = 0o377 // 八进制 255
let n3 = 0b11111111 // 二进制 255
alert(n === n2)
alert(n2 === n3)
toString(base)
虽然以其他进制保存了数字,但其值在显示的时候仍是以十进制显示。
$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255
alert(n) // 255
如果我们要以其他进制显示,就要手动调用 toString(base)
方法。 toString
可以将一个数字类型转换为字符串类型, base
参数表示进制,默认值为十进制。
$$jsdemo$$
$$edit$$
let n = 0xff // 十六进制 255
alert(typeof n) // number
alert(typeof n.toString()) // string
alert(n.toString(16)) // ff
alert(n.toString(2)) // 11111111
$$tip
使用 toString(base)
的场所是一些需要特定十六进制字符的场所,比如颜色取值。
$$
toFixed(digits)
toFixed(digits)
方法同样可以将一个数字转成字符串,但同样还能以四舍五入的方式决定保留固定的小数位数。
$$jsdemo$$
$$edit$$
let n = 123.45
alert(typeof n.toFixed()) // string
alert(n.toFixed()) // 123
alert(n.toFixed(1)) // 123.5
alert(n.toFixed(4)) // 123.4500
toPrecision(precision)
toPrecision(precision)
同样是将一个数字转成字符串,不同的是四舍五入到指定的精度。
$$jsdemo$$
$$edit$$
let n = 123.45
alert(typeof n.toPrecision()) // string
alert(n.toPrecision()) // 123.45
alert(n.toPrecision(1)) // 1e+2,也就是 100
alert(n.toPrecision(4)) // 123.5
字符串转数字
字符串转数字一般有两种方法,使用 Number()
或 parseInt
。
对于已经以特定标识开头的不同进制字符串, Number()
和 parseInt()
都能做到很好的转换。
$$jsdemo$$
$$edit$$
let n = Number("0xff") // 255
let n2 = parseInt("0xff") // 255
alert(n) // 255
alert(typeof n) // number
alert(n === n2) // true
但如果没以特定标识开头的字符串,就必须用 parseInt()
转换,在第二个参数中标明进制。
$$jsdemo$$
$$edit$$
let n = parseInt("ff", 16) // 按16进制转换
alert(n) // 255
$$warning
parseInt()
只能进行整数的转换。
$$
parseFloat
parseFloat()
可以将一个浮点数字符串转换为数字类型。
$$jsdemo$$
$$edit$$
let n = parseFloat("2.22")
alert(n) // 2.22
alert(typeof n) // number
$$tip
以上方法都来自 Number
类型的自带方法,有关 Number
类型所有属性与方法的完整介绍请看 Number - MDN。
$$
数学运算库
Math
是一个内置的对象,包含了一些数学运算的属性或方法,以下章节会介绍一些常用的属性或方法,详情可以参考 Math - MDN 。
$$warning
Math
只用用于 Number
类型,不支持 BigInt
类型。
$$
常用属性
Math.E // 欧拉常数,约等于 2.718。
Math.LN2 // 2 的自然对数,约等于 0.693。
Math.LN10 // 10 的自然对数,约等于 2.303。
Math.LOG2E // 以 2 为底的 E 的对数,约等于 1.443。
Math.LOG10E // 以 10 为底的 E 的对数,约等于 0.434。
Math.PI // 圆周率,一个圆的周长和直径之比,约等于 3.14159。
Math.SQRT1_2 // 2 的平方根的倒数,约等于 0.707。
Math.PI // 圆周率,一个圆的周长和直径之比,约等于 3.14159。
Math.SQRT2 // 2 的平方根,约等于 1.414。
常用方法
绝对数
Math.abs(x)
可以返回一个数的绝对数。
Math.abs(10) // 10
Math.abs(-10) // 10
四舍五入
Math.round(x)
返回一个数四舍五入后的整数。
Math.round(2.5) // 3
Math.round(2.4) // 2
向上取整
Math.ceil(x)
返回大于一个数的最小整数,即一个数向上取整的结果。
Math.ceil(2.1) // 3
Math.ceil(2.4) // 3
向下取整
Math.floor(x)
返回小于一个数的最大整数,即一个数向下取整的结果。
Math.floor(2.6) // 2
Math.floor(2.9) // 2
舍去小数
Math.trunc(x)
方法会舍去数字的小数部分,只保留整数,注意与 Math.floor(x)
向下取整的区别。
Math.trunc(1.2) // 1
Math.trunc(-1.2) // -1
Math.floor(1.2) // 1
Math.floor(-1.2) // -2
随机数
Math.random()
返回一个 在 0
(包括)至 1
(不包括)之间的浮点数。
$$jsdemo$$
$$edit$$
alert(Math.random()) // 每次结果都不一样
实例:返回区间内的随机数
Math.random()
只能返回 0 和 1 之间的数,以下实现了一个返回 a(包含)、b(不包含)区间内的数。
$$jsdemo$$
$$edit$$
function ranIn(a, b) {
let diff = b - a // 先求出他们的差值
let result = diff * Math.random() // 再与随机数相乘
return result + a // 最后加上 a 即可
}
// 返回 2(包含)、6(不包含)之间的任意数
alert(ranIn(2, 6))
精度损失
精度损失说是一些小数运算后与实际结果出现偏差的情况。
$$jsdemo$$
$$edit$$
alert(0.1 + 0.2 == 0.3) // false
alert(0.1 + 0.2) // 0.30000000000000004
这是因为小数在计算机中是以二进制进行保存与运算,当一些小数用二进制表示时是一个无限的二进制,就会损失一些精度。
解决思路
- 能以整数运算的以整数运算,比如价格以分作为单位,只有在显示时将其除以 100 后显示。
- 对于精度要求不高的场景使用
toFixed
保留对应精度,应注意此时返回的是字符串。 - 引入第三方类型库,比如 decimal.js、bignumber.js、big.js 都是一些很优秀的高精度计算库。
练习
- 实现一个函数
ranInt
返回两个参数 a、b 间的随机整数,包含 a、b。
function ranInt(a, b) {
// 补充完成
}
alert(ranInt(4, 9)) // 随机整数
$$demo
<body>
<button onclick="show()">演示实例</button>
</body>
<script>
function show() {
function ranInt(a, b) {
let diff = b - a
diff = diff * Math.random()
let result = a + diff
result = Math.round(result)
return result
}
alert(ranInt(4, 9)) // 随机整数
}
</script>
$$
$$answer
$$jsdemo$$
$$edit$$
function ranInt(a, b) {
let diff = b - a
diff = diff * Math.random()
let result = a + diff
result = Math.round(result)
return result
}
alert(ranInt(4, 9)) // 随机整数
$$
- 结合餐饮数据完成以下餐饮建议程序,注意点 5 次以上的结果。
let lunches = [
"牛肉面",
"盖浇饭",
"蛋炒饭",
"烧饼",
"黄焖鸡",
"麻辣烫",
"烤鸭",
]
$$demo <div class="container"> <h1 class="tip">让我来决定你午餐吃啥~</h1> <!-- <h1 class="tip">今天午餐吃:<span class="lunch">牛肉面</span></h1> --> <button class="btn" onclick="ranLunch()">随机大餐</button> </div>
<style> .container { text-align: center; }
.lunch {
color: teal;
font-size: 1.2em;
}
</style> <script> let lunches = [ "牛肉面", "盖浇饭", "蛋炒饭", "烧饼", "黄焖鸡", "麻辣烫", "烤鸭", ]
function ranChoose(array) {
// 从数组中随机选择一个元素
let idx = array.length * Math.random()
idx = Math.floor(idx)
return array[idx]
}
let counter = 0
function ranLunch() {
// 随机大餐
counter++
if (counter <= 5) {
// 小于等于 5 次提供建议
let lunch = ranChoose(lunches)
document.querySelector(".tip").outerHTML = `
<h1 class="tip">今天午餐吃:<span class="lunch">${lunch}</span></h1>
`
} else {
// 大于 5 次不伺候
document.querySelector(".tip").outerHTML = `
<h1 class="tip">太挑剔了不伺候</span></h1>
`
document.querySelector(".btn").disabled = true
}
}
</script> $$
$$answer
$$jsdemo$$
$$edit$$
<div class="container">
<h1 class="tip">让我来决定你午餐吃啥~</h1>
<!-- <h1 class="tip">今天午餐吃:<span class="lunch">牛肉面</span></h1> -->
<button class="btn" onclick="ranLunch()">随机大餐</button>
</div>
<style>
.container {
text-align: center;
}
.lunch {
color: teal;
font-size: 1.2em;
}
</style>
<script>
let lunches = [
"牛肉面",
"盖浇饭",
"蛋炒饭",
"烧饼",
"黄焖鸡",
"麻辣烫",
"烤鸭",
]
function ranChoose(array) {
// 从数组中随机选择一个元素
let idx = array.length * Math.random()
idx = Math.floor(idx)
return array[idx]
}
let counter = 0
function ranLunch() {
// 随机大餐
counter++
if (counter <= 5) {
// 小于等于 5 次提供建议
let lunch = ranChoose(lunches)
document.querySelector(".tip").outerHTML = `
<h1 class="tip">今天午餐吃:<span class="lunch">${lunch}</span></h1>
`
} else {
// 大于 5 次不伺候
document.querySelector(".tip").outerHTML = `
<h1 class="tip">太挑剔了不伺候</span></h1>
`
document.querySelector(".btn").disabled = true
}
}
</script>
$$