1. JavaScript 基础

  2. Document

  3. 运算符

  4. 深入数据和类型

  5. 函数进阶

  6. 原型、继承

  7. 浏览器存储

  8. Web API

  9. 事件

  10. 错误处理

  11. 异步编程

  12. 网络请求

  13. 模块

  14. 练习

  15. 实例

  16. 工具与规范

  17. 软件架构模式

  18. 设计模式

本章是数字类型的进阶讲解,有关数字类型的初步介绍请看 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.jsbignumber.jsbig.js 都是一些很优秀的高精度计算库。

练习

  1. 实现一个函数 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)) // 随机整数

$$

  1. 结合餐饮数据完成以下餐饮建议程序,注意点 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>

$$