Skip to content

1-15对象和对象操作(二) ​

本页对应 第一章JavaScript基础,共 4 段视频,约 45 分钟。

学习目标 ​

  • 能识别并编写对象数组,使用传统 for 循环遍历数组,并通过 数组名[i].属性名 取出每个对象的指定属性值。
  • 能根据对象数组的数据条数,使用模板字符串和循环拼接表格行 <tr>,并将结果插入 tbody,实现数据驱动的表格渲染。
  • 能说明 Math 是 JavaScript 内置数学对象,并能正确调用 Math.PI、Math.max()、Math.min()、Math.abs()、Math.ceil()、Math.floor()、Math.round() 完成对应数学运算。
  • 能区分 Math.ceil()、Math.floor()、Math.round() 在正数和负数场景下的取整规则,并正确预测和验证运行结果。
  • 能使用 Math.random() 生成 [0, 1) 范围内的随机小数,并说明其“能取到 0、取不到 1”的取值范围特点。
  • 能推导并运用 Math.floor(Math.random() * (m - n + 1)) + n 生成 n 到 m 之间的随机整数,并通过多次运行验证边界值。

知识点 ​

从 console.log 认识内置对象 ​

为什么需要:JavaScript 已经帮我们准备了一些常用对象,开发者不用从零写起,直接调用属性和方法即可,能提高开发效率。
怎么想:先分清“对象”和“对象里的方法”。console 是内置对象,log 是它里面的方法,所以写成 console.log()。
怎么做:遇到 Math、document 这类名字,先意识到它们可能是内置对象,再通过“对象.属性”或“对象.方法()”调用。
易错点:转写稿里把 Math 说成“mice/ms”,这是口误或同音,正确写法是 Math;方法后面要加小括号,属性一般不加。

Math 数学对象:属性和常用方法 ​

为什么需要:做数学运算时,圆周率、最大值、最小值、绝对值、取整等都很常见,Math 把这些能力内置好了。
怎么想:先看它是属性还是方法。Math.PI 是属性;Math.max()、Math.ceil() 是方法。取整类要结合数轴理解“往大取”还是“往小取”。
怎么做:按下表调用,并通过 console.log 观察结果。

属性/方法作用说明
PI圆周率Math.PI 属性,返回圆周率
max找最大值Math.max(8, 3, 1) 方法,返回 8
min找最小值Math.min(8, 3, 1) 方法,返回 1
abs绝对值Math.abs(-1) 方法,返回 1
ceil向上取整Math.ceil(3.1) 方法,返回 4
floor向下取整Math.floor(3.8) 方法,返回 3
round四舍五入取整Math.round(3.8) 方法,返回 4, 遇到.5则舍入到相邻的在正无穷(+∞)方向上的整数

易错点:max/min 的小括号里放数字,不要直接放数组;ceil 可记成“天花板”,往大了取;floor 可记成“地板”,往小了取。转写稿调试时特别强调负数:Math.ceil(-1.1) 得 -1,因为 -1 比 -2 大;Math.floor(-1.1) 得 -2,因为 -2 更小。Math.round(-1.5) 得 -1,因为 .5 要往正无穷方向取。

javascript
<script>
  // 内置对象Math 
  // 1. PI 属性 圆周率
  console.log(Math.PI)

// 2. max  方法 找最大值
console.log(Math.max(8, 4, 2)) // 8

// 3. min  方法 找最小值
console.log(Math.min(8, 4, 2)) // 2

// 4. abs 方法 取绝对值 
console.log(Math.abs(-1))  // 1

// 5. ceil 方法 向上取整   ceil 天花板   往大了取
console.log(Math.ceil(1.1)) // 2
console.log(Math.ceil(1.5)) // 2
console.log(Math.ceil(1.8)) // 2
console.log(Math.ceil(-1.1)) //  -1
console.log(Math.ceil(-1.5)) //  -1
console.log(Math.ceil(-1.8)) //  -1

// 6. floor 方法 向下取整  floor 地板  往小了取
console.log(Math.floor(1.1)) // 1
console.log(Math.floor(1.5)) // 1
console.log(Math.floor(1.8)) // 1
console.log(Math.floor(-1.1)) //  -2
console.log(Math.floor(-1.5)) //  -2
console.log(Math.floor(-1.8)) //  -2

// 7. round 方法 四舍五入取整 
console.log(Math.round(1.1)) // 1
console.log(Math.round(1.5)) // 2
console.log(Math.round(1.8)) // 2
console.log(Math.round(-1.1)) // -1
console.log(Math.round(-1.8)) // -2
console.log(Math.round(-1.5)) // -1
</script>

随机数 random ​

为什么需要:随机点名、随机抽奖、随机取数组元素都需要随机整数,而 Math.random() 正好能提供随机小数。
怎么想:Math.random() 返回 [0, 1),即能取到 0、取不到 1,数学上叫“左闭右开”。要 0~10 的随机整数,就把它乘 (10 + 1),再向下取整。
怎么做:先乘范围,再 Math.floor 去掉小数。转写稿的推导是:(0~0.999…) * 11 得到 0~10.999…,向下取整后就是 0~10。5~15 可先做 0~10,再加 5。
易错点:不要忘记 +1;不要用 ceil 代替 floor;边界调试时可多刷新几次,观察能取到 0 和 10、5 和 15,但不会出现 11 或 16。

如何生成0-10的随机整数呢?

javascript
Math.floor(Math.random() * (10 + 1))

如何生成5-15的随机整数?

javascript
Math.floor(Math.random() * (10 + 1)) + 5

如何生成N-M之间的随机整数

javascript
Math.floor(Math.random() * (M - N + 1)) + N
Math.floor(Math.random() * (差值 + 1)) + 最小值
javascript
<script>
  // 1. Math随机数  Math.random() 
  // 1.1 随机的小数 0 ~1 之间
  // 1.2 能取到0,但是取不到1 [0, 1)
  // console.log(Math.random())

  // 2. 取 0 ~ 10 之间的一个随机整数
  // Math.random() * (10 + 1)
  // (0 ~ 0.99999) * 11
  // 0 ~ 10.99999
  // Math.floor(Math.random() * (10 + 1))
  // console.log(Math.floor(Math.random() * (10 + 1)))

  // 3. 取 5 ~ 15 之间的一个随机整数
  // Math.floor(Math.random() * (10 + 1))  0 ~ 10 
  // Math.floor(Math.random() * (10 + 1)) + 5  5 ~ 15 
  // console.log(Math.floor(Math.random() * (10 + 1)) + 5)

  // 4. 取 n ~ m 之间的一个随机整数  4 ~ 12 
  // Math.floor(Math.random() * (差值 + 1)) + 最小值
  console.log(Math.floor(Math.random() * (8 + 1)) + 4)
</script>

案例需求与效果 ​

综合案例效果图

本节要做一个“学成在线”精品课程列表的综合案例:根据对象数组中的数据,渲染出多个课程列表项。
为什么需要:真实页面中的课程、商品、学生信息通常不是手写死的,而是来自一组结构化数据;数据一变,页面就应跟着变。
怎么想:先准备对象数组,再循环数组,把每个对象拼成一段li标签字符串,最后把字符串写入页面容器。
怎么做:核心是“对象数组 + for循环 + 模板字符串拼接 + document.write渲染”。
易错点:不要把数组和对象混淆;data[i]才是数组中的某个对象,data[i].title才是对象属性。

用对象数组组织数据 ​

为什么需要:一个课程包含图片、标题、学习人数等多个信息,用多个变量保存很麻烦;把“课程对象”放进数组,就能描述一组课程。
怎么想:转写稿中讲对象数组时,先用students[i]取出数组中的每个对象,再用students[i].home取对象属性。本案例同理:data是数组,data[i]是课程对象。
怎么做:定义let data = [...],每项包含src、title、num。
易错点:data.length表示对象个数;循环条件写i < data.length,不要写i <= data.length,否则会取到undefined。

循环拼接字符串生成标签 ​

为什么需要:有11条数据就手写11个li,数据一变就要改HTML,维护成本高。
怎么想:先准备空字符串let str = '',循环一次就向str追加一个li;循环结束后,str里就是所有列表项。
怎么做:用传统for循环遍历数组,在模板字符串中通过\${data[i].src}、\${data[i].title}、\${data[i].num}填入真实数据。转写稿里调试表格案例时,会先console.log(str)检查是否生成了对应行数;本案例也可以先打印str,确认拼接结果再写入页面。
易错点:模板字符串要用反引号;${}不能写成$();<li>标签要成对闭合;图片路径./uploads/...要真实存在。

写入容器完成渲染 ​

为什么需要:拼接出的字符串还只是“字符串”,必须放进页面的ul容器中,浏览器才会把它解析成标签。
怎么想:先搭好课程模块外层结构.course.wrapper,再在.bd中的ul.common里放入\${str}。
怎么做:用document.write()输出整段模板字符串,把前面生成的str插入ul内部。
易错点:ul的类名要与CSS对应;document.write中的模板字符串里又嵌套了\${str},注意反引号成对;脚本写在body中时,生成内容会写入当前脚本位置。

完整代码 ​

html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>学成在线</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="./css/base.css">
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>

  <!-- 精品课程 -->
  <script>
    // 综合案例代码
    // 1. 利用对象数组的数据渲染页面
    // 综合案例代码
    let data = [
      {
        src: './uploads/quality01.png',
        title: 'JavaScript数据看板项目实战',
        num: 1125
      },
      {
        src: './uploads/quality02.png',
        title: 'Vue.js实战——面经全端项目',
        num: 2726
      },
      {
        src: './uploads/quality03.png',
        title: '玩转Vue全家桶,iHRM人力资源项目',
        num: 9456
      },
      {
        src: './uploads/quality04.png',
        title: 'Vue.js实战医疗项目——优医问诊',
        num: 7192
      },
      {
        src: './uploads/quality05.png',
        title: '小程序实战:小兔鲜电商小程序项目',
        num: 2703
      },
      {
        src: './uploads/quality06.png',
        title: '前端框架Flutter开发实战',
        num: 2841
      },
      {
        src: './uploads/quality07.png',
        title: '熟练使用React.js——极客园H5项目',
        num: 95682
      },
      {
        src: './uploads/quality08.png',
        title: '熟练使用React.js——极客园PC端项目',
        num: 904
      },
      {
        src: './uploads/quality09.png',
        title: '前端实用技术,Fetch API 实战',
        num: 1516
      },
      {
        src: './uploads/quality10.png',
        title: '前端高级Node.js零基础入门教程',
        num: 2766
      },
      {
        src: './uploads/quality10.png',
        title: '前端高级Node.js零基础入门教程',
        num: 27669
      }
    ]
    // 2. 利用循环来做字符串拼接生成多个li标签,之后把生成的li标签放入容器 ul 里面渲染即可
    let str = ''
    for (let i = 0; i < data.length; i++) {
      // console.log(data[i]) // 每个对象
      str += `
`<li>`
          <a href="#">
            <div class="pic">
              <img src="\${data[i].src}" alt="">
            </div>
            <h4>\${data[i].title}</h4>
            <p><span>高级</span> · <i>\${data[i].num}</i>人在学习</p>
          </a>
        </li>
      `
    }
    console.log(str)

    document.write(`
      <div class="course wrapper">
        <div class="hd">
          <h3>精品推荐</h3>
          <a href="#">查看全部
            <span class="iconfont icon-arrow-right-bold">
            </span>
          </a>
        </div>
        <div class="bd">
          <ul class="common">
            \${str}
          </ul>
        </div>
      </div>
    `)

  </script>
</body>

</html>

调试与验证 ​

为什么需要:字符串拼接时少一个反引号、少一个},页面就可能空白或结构错乱。
怎么想:先验证数据,再验证拼接,最后验证渲染。
怎么做:先console.log(data.length)看条数;再console.log(str)看是否生成多个li;最后刷新页面检查图片、标题、人数。
易错点:num是数字,直接插入即可;若图片不显示,先查src路径;若列表样式不对,查ul.common和CSS类名是否一致。数据增加后无需改HTML,列表会自动多出一项,这正是数据驱动渲染的价值。

课件图示 ​

课件第27页:1.4 内置对象 l 内置对象:JavaScript内部提供的对象,包含各种属性

课件第28页:1.4 内置对象-Math l 介绍:Math对象是JavaScript提供的一

课件第29页:1.4 内置对象Math-生成任意范围随机数 l Math.random() 随

代码示例 ​

示例一:Math 内置对象的属性与方法 ​

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Math 内置对象</title>
</head>
<body>
  <script>
    // 内置对象 Math
    // 1. PI 属性 圆周率
    console.log(Math.PI)

    // 2. max 方法 找最大值
    console.log(Math.max(8, 4, 2)) // 8

    // 3. min 方法 找最小值
    console.log(Math.min(8, 4, 2)) // 2

    // 4. abs 方法 取绝对值
    console.log(Math.abs(-1)) // 1

    // 5. ceil 方法 向上取整  ceil 天花板  往大了取
    console.log(Math.ceil(1.1)) // 2
    console.log(Math.ceil(1.5)) // 2
    console.log(Math.ceil(1.8)) // 2
    console.log(Math.ceil(-1.1)) // -1
    console.log(Math.ceil(-1.5)) // -1
    console.log(Math.ceil(-1.8)) // -1

    // 6. floor 方法 向下取整  floor 地板  往小了取
    console.log(Math.floor(1.1)) // 1
    console.log(Math.floor(1.5)) // 1
    console.log(Math.floor(1.8)) // 1
    console.log(Math.floor(-1.1)) // -2
    console.log(Math.floor(-1.5)) // -2
    console.log(Math.floor(-1.8)) // -2

    // 7. round 方法 四舍五入取整
    console.log(Math.round(1.1)) // 1
    console.log(Math.round(1.5)) // 2
    console.log(Math.round(1.8)) // 2
    console.log(Math.round(-1.1)) // -1
    console.log(Math.round(-1.8)) // -2
    console.log(Math.round(-1.5)) // -1
  </script>
</body>
</html>

关键行与易错点

  • Math 是内置的数学对象,PI 是属性(不带小括号),max / min / abs / ceil / floor / round 都是方法(必须带小括号),写成 Math.PI 而不是 Math.pi,Math 的 M 要大写。
  • Math.max() / Math.min() 括号里只能放数字,不能直接放数组,否则得不到最大值最小值。
  • ceil 记成“天花板”、floor 记成“地板”:ceil 往大了取、floor 往小了取,负数时最容易错——Math.ceil(-1.1) 是 -1(比 -2 大),Math.floor(-1.1) 是 -2(比 -1 小)。
  • round 普通小数看离哪边近;遇到 .5 这种正好在中间的,舍入到正无穷方向的整数,所以 Math.round(-1.5) 是 -1 而不是 -2。

示例二:Math.random 生成随机整数 ​

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Math.random 随机数</title>
</head>
<body>
  <script>
    // 1. Math随机数 Math.random()
    // 1.1 随机的小数 0 ~ 1 之间
    // 1.2 能取到0,但是取不到1 [0, 1)
    console.log(Math.random())

    // 2. 取 0 ~ 10 之间的一个随机整数
    // Math.random() * (10 + 1)
    // (0 ~ 0.99999) * 11
    // 0 ~ 10.99999
    // Math.floor(Math.random() * (10 + 1))
    console.log(Math.floor(Math.random() * (10 + 1)))

    // 3. 取 5 ~ 15 之间的一个随机整数
    // Math.floor(Math.random() * (10 + 1))        0 ~ 10
    // Math.floor(Math.random() * (10 + 1)) + 5    5 ~ 15
    console.log(Math.floor(Math.random() * (10 + 1)) + 5)

    // 4. 取 n ~ m 之间的一个随机整数  4 ~ 12
    // Math.floor(Math.random() * (差值 + 1)) + 最小值
    console.log(Math.floor(Math.random() * (8 + 1)) + 4)
  </script>
</body>
</html>

关键行与易错点

  • Math.random() 返回 [0, 1) 的随机小数:能取到 0,取不到 1(左闭右开)。
  • 因为取不到 1,所以公式里必须 (差值 + 1),少加这个 1 就永远取不到最大值;最后一定要用 Math.floor 把小数“砍掉”,不能用 Math.ceil(会把范围撑大)。
  • 通用公式:Math.floor(Math.random() * (M - N + 1)) + N,其中 M - N 是最大值减最小值的差值,N 是最小值。
  • 5~15 的例子本质是“0~10 的公式整体 +5”,因为差值 15 - 5 = 10;0~10 的例子最小值是 0,加 0 和不加一样,所以看起来没写 + 0。

示例三:综合案例——根据对象数组渲染列表页面 ​

js
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>学成在线</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css">
  <link rel="stylesheet" href="./css/base.css">
  <link rel="stylesheet" href="./css/index.css">
</head>
<body>

  <!-- 精品课程 -->
  <script>
    // 综合案例代码
    // 1. 利用对象数组的数据渲染页面
    let data = [
      {
        src: './uploads/quality01.png',
        title: 'JavaScript数据看板项目实战',
        num: 1125
      },
      {
        src: './uploads/quality02.png',
        title: 'Vue.js实战——面经全端项目',
        num: 2726
      },
      {
        src: './uploads/quality03.png',
        title: '玩转Vue全家桶,iHRM人力资源项目',
        num: 9456
      },
      {
        src: './uploads/quality04.png',
        title: 'Vue.js实战医疗项目——优医问诊',
        num: 7192
      },
      {
        src: './uploads/quality05.png',
        title: '小程序实战:小兔鲜电商小程序项目',
        num: 2703
      },
      {
        src: './uploads/quality06.png',
        title: '前端框架Flutter开发实战',
        num: 2841
      },
      {
        src: './uploads/quality07.png',
        title: '熟练使用React.js——极客园H5项目',
        num: 95682
      },
      {
        src: './uploads/quality08.png',
        title: '熟练使用React.js——极客园PC端项目',
        num: 904
      },
      {
        src: './uploads/quality09.png',
        title: '前端实用技术,Fetch API 实战',
        num: 1516
      },
      {
        src: './uploads/quality10.png',
        title: '前端高级Node.js零基础入门教程',
        num: 2766
      },
      {
        src: './uploads/quality10.png',
        title: '前端高级Node.js零基础入门教程',
        num: 27669
      }
    ]

    // 2. 利用循环来做字符串拼接生成多个li标签,之后把生成的li标签放入容器 ul 里面渲染即可
    let str = ''
    for (let i = 0; i < data.length; i++) {
      // console.log(data[i]) // 每个对象
      str += `
         <li>
          <a href="#">
            <div class="pic">
              <img src="${data[i].src}" alt="">
            </div>
            <h4>${data[i].title}</h4>
            <p><span>高级</span> · <i>${data[i].num}</i>人在学习</p>
          </a>
        </li>
      `
    }
    console.log(str)

    document.write(`
      <div class="course wrapper">
        <div class="hd">
          <h3>精品推荐</h3>
          <a href="#">查看全部
            <span class="iconfont icon-arrow-right-bold">
            </span>
          </a>
        </div>
        <div class="bd">
          <ul class="common">
            ${str}
          </ul>
        </div>
      </div>
    `)
  </script>
</body>
</html>

关键行与易错点

  • data 是对象数组(数组里存的是对象),所以遍历的是数组,用传统 for 循环:for (let i = 0; i < data.length; i++),不要写成 for...in。
  • data[i] 拿到的是数组里的每一个对象,再通过 data[i].src、data[i].title、data[i].num 这种“对象.属性”的方式取出具体值。
  • 拼接必须先用 let str = '' 准备一个空字符串,循环里用 str += 累加;如果写成 str =,最后只剩一条数据。
  • 模板字符串里的 ${} 中直接写 data[i].src 即可,别再手写 + 号拼接,也不要在 ${} 外面再加引号,否则属性值会变成死字符串。
  • 用 document.write() 输出时,\${str} 要放在 <ul class="common"> 内部,生成的多个 li 才会成为 ul 的子元素;页面上有几个 li 完全由 data 的长度决定,增删数据不需要改页面结构。

常见错误 ​

1. 把数组直接丢给 Math.max / Math.min

  • 现象:Math.max([8, 3, 1]) 得到 NaN,而不是 8。
  • 原因:这两个方法接收的是"一串数字参数",不是"一个数组",数组被当成一个值参与比较,转数字失败。
  • 修法:展开后再传 Math.max(...arr),或 Math.max.apply(null, arr);只传数字时直接用 Math.max(8, 3, 1)。

2. 大小写写错,拿到 undefined 或直接报错

  • 现象:Math.pi 得到 undefined;math.PI 直接抛 ReferenceError: math is not defined。
  • 原因:JS 区分大小写,对象名 Math、属性名 PI 都是固定写法。
  • 修法:Math.PI;遇到 undefined 先回头看属性名拼写,而不是怀疑公式。

3. 负数取整方向搞反

  • 现象:以为 Math.ceil(-1.1) 是 -2,实际是 -1;以为 Math.floor(-1.1) 是 -1,实际是 -2。
  • 原因:把"向上/向下"理解成了"绝对值变大/变小",而它指的是数轴上的方向。
  • 修法:写负数前先在纸上画数轴,ceil 往右(+∞)、floor 往左(-∞);正数场景两者结果才是"去掉小数"。

4. Math.round(-1.5) 与直觉不符

  • 现象:期望 -2,实际得到 -1。
  • 原因:.5 的舍入方向固定朝 +∞,不是"远离零"。
  • 修法:需要"远离零"的四舍五入时写 Math.sign(x) * Math.round(Math.abs(x));普通业务(金额、评分)用默认行为即可。

5. 随机整数公式差 1,或边界永远取不到

  • 现象:想要 0~10 却写成 Math.floor(Math.random() * 10),10 永远出不来;想要 5~15 写成 Math.floor(Math.random() * 15) + 5,只能到 19 以内的错误区间。
  • 原因:Math.random() 取不到 1,区间长度必须 +1 补齐;起始值只能加在最后。
  • 修法:死记模板 Math.floor(Math.random() * (max - min + 1)) + min,任何范围都套它,不要临时推导。

6. 用 Math.round 生成随机整数,边界概率减半

  • 现象:Math.round(Math.random() * 10) 能出 0~10,但统计下来 0 和 10 出现的次数只有其它数字的一半。
  • 原因:round 把 [0, 0.5) 都归到 0,把 [9.5, 10] 归到 10,而中间每个整数各占一个完整区间。
  • 修法:随机取整一律用 Math.floor,不要用 round。

7. 渲染时数据取不到,页面出现 undefined

  • 现象:列表里每行都显示 undefined,或最后多出一行空白。
  • 原因:\${data.src} 少写了索引(data 是数组不是对象);或循环条件写成 i <= data.length,多跑一轮越界。
  • 修法:模板里统一写 \${data[i].属性名};循环条件固定 i < data.length。出现 undefined 先查索引。

8. 字符串拼接用 = 而不是 +=,只渲染最后一条

  • 现象:数据有 10 条,页面只出现 1 条。
  • 原因:每轮循环都用 str = ... 覆盖了上一轮结果。
  • 修法:let str = '' 初始化,循环内 str += ...;变量必须初始化为空串,否则开头会多一个 undefined。

练习 ​

练习 1|取整预测

先不运行,写出下面每行的结果,再在控制台验证,错一个就把那条抄在笔记里:

javascript
Math.ceil(-2.3)   // ?
Math.floor(-2.3)  // ?
Math.round(-2.5)  // ?
Math.round(2.5)   // ?
Math.abs(-2.3)    // ?

练习 2|封装随机函数

写一个 randomInt(min, max),返回 [min, max] 闭区间内的随机整数(min、max 都能取到)。然后用它从笔记里的 data 数组中随机抽一门课,把标题打印到控制台。要求:连续刷新 20 次,结果里必须出现过 data 的第一条和最后一条。

练习 3|数据驱动渲染

用下面数组渲染成一个 <ul>,每行格式为 序号. 姓名(年龄):

javascript
let students = [
  { name: '小明', age: 18 },
  { name: '小红', age: 19 },
  { name: '小刚', age: 17 }
]

要求:① 序号从 1 开始;② 渲染完成后,往数组末尾再 push 一条数据并重新渲染,页面自动变成 4 行,不需要改动任何 HTML。

练习 4|骰子统计

模拟掷骰子 1000 次(1~6 点),统计每个点数出现的次数并打印。跑完后回答:如果 6 个数字出现次数差距很大(比如某个点 300 次),问题最可能出在哪一行?

练习 5|找 bug

下面的代码想让页面渲染出 3 个课程标题,找出至少 3 处问题并改正:

javascript
let data = [{ title: 'A' }, { title: 'B' }, { title: 'C' }]
let str
for (let i = 0; i <= data.length; i++) {
  str = `<li>${data.title}</li>`
}
document.body.innerHTML = str

原视频对照 ​

#视频时长
1对象数组案例07:25
2渲染表格案例10:53
3Math内置对象15:50
4Math.random生成随机数11:33

小结 ​

  1. Math 是直接拿来用的工具对象,所有成员都是 Math.xxx 的调用形式,永远不要 new Math(),也不要把它的方法当成全局函数直接写 max()。
  2. 取整三兄弟在正数上"看起来都对",真正的分歧全在负数——只要出现负数,先画数轴再写代码。
  3. 随机整数只有一个模板:Math.floor(Math.random() * (max - min + 1)) + min,任何范围都套它,不要现场推导;取整一定用 floor,用 round 会让两端概率减半。
  4. 对象数组 + for 循环 + 模板字符串 += 拼接 + 一次性写入容器,是"数据驱动渲染"的最小原型;后面学的框架列表渲染,本质还是这一步。
  5. 页面渲染出几行由 data.length 决定,不由 HTML 决定;数据改了页面就变,这才是这套写法真正的价值。
  6. 渲染结果出现 undefined,九成是三种情况:少了 [i]、循环条件用了 <=、字符串没初始化为空串或用 = 覆盖了。
  7. 写入容器优先用 innerHTML,document.write 只在页面加载过程中可靠,一旦放进事件回调里会把整页清空。