JavaScript基础

自用

JavaScript 基础 - 第1天

了解变量、数据类型、运算符等基础概念,能够实现数据类型的转换,结合四则运算体会如何编程。

  • 体会现实世界中的事物与计算机的关系
  • 理解什么是数据并知道数据的分类
  • 理解变量存储数据的“容器”
  • 掌握常见运算符的使用,了解优先级关系
  • 知道 JavaScript 数据类型隐式转换的特征

介绍

掌握 JavaScript 的引入方式,初步认识 JavaScript 的作用

引入方式

JavaScript 程序不能独立运行,它需要被嵌入 HTML 中,然后浏览器才能执行 JavaScript 代码。通过 script 标签将 JavaScript 代码引入到 HTML 中,有两种方式:

内部方式

通过 script 标签包裹 JavaScript 代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 引入方式</title>
</head>
<body>
  <!-- 内联形式:通过 script 标签包裹 JavaScript 代码 -->
  <script>
    alert('嗨,欢迎来传智播学习前端技术!')
  </script>
</body>
</html>
外部形式

一般将 JavaScript 代码写在独立的以 .js 结尾的文件中,然后通过 script 标签的 src 属性引入

1
2
// demo.js
document.write('嗨,欢迎来传智播学习前端技术!')
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 引入方式</title>
</head>
<body>
  <!-- 外部形式:通过 script 的 src 属性引入独立的 .js 文件 -->
  <script src="demo.js"></script>
</body>
</html>

如果 script 标签使用 src 属性引入了某 .js 文件,那么标签内的代码会被忽略!!!如下代码所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 引入方式</title>
</head>
<body>
  <!-- 外部形式:通过 script 的 src 属性引入独立的 .js 文件 -->
  <script src="demo.js">
    // 此处的代码会被忽略掉!!!!
  	alert(666);  
  </script>
</body>
</html>

:一般把写在上方(并无硬性要求)

注释和结束符

通过注释可以屏蔽代码被执行或者添加备注信息,JavaScript 支持两种形式注释语法:

单行注释

使用 // 注释单行代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 注释</title>
</head>
<body>
  
  <script>
    // 这种是单行注释的语法
    // 一次只能注释一行
    // 可以重复注释
    document.write('嗨,欢迎来传智播学习前端技术!');
  </script>
</body>
</html>
多行注释

使用 /* */ 注释多行代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 注释</title>
</head>
<body>
  
  <script>
    /* 这种的是多行注释的语法 */
    /*
    	更常见的多行注释是这种写法
    	在些可以任意换行
    	多少行都可以
      */
    document.write('嗨,欢迎来传智播学习前端技术!')
  </script>
</body>
</html>

注:编辑器中单行注释的快捷键为 ctrl + /

结束符

在 JavaScript 中 ; 代表一段代码的结束,多数情况下可以省略 ; 使用回车(enter)替代。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 结束符</title>
</head>
<body>
  
  <script> 
    alert(1);
    alert(2);
    alert(1)
    alert(2)
  </script>
</body>
</html>

实际开发中有许多人主张书写 JavaScript 代码时省略结束符 ;

输入和输出

输出和输入也可理解为人和计算机的交互,用户通过键盘、鼠标等向计算机输入信息,计算机处理后再展示结果给用户,这便是一次输入和输出的过程。

举例说明:如按键盘上的方向键,向上/下键可以滚动页面,按向上/下键这个动作叫作输入,页面发生了滚动了这便叫输出。

输出

JavaScript 可以接收用户的输入,然后再将输入的结果输出:

alert()document.wirte()console.log()

以数字为例,向 alert()document.write()输入任意数字,他都会以弹窗形式展示(输出)给用户。

例子1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      alert('这是一个对话框')
    </script>
</body>
</html>

效果:

image-20241014205511824

例子2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
        document.write('这是一句话')
        document.write('<h1>我是h1标题</h1>')
    </script>
</body>
</html>

效果:

image-20241014204951701

例子3:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      console.log('在这呢')
    </script>
</body>
</html>

效果:

image-20241014210231148

输入

prompt() 输入任意内容会以弹窗形式出现在浏览器中,一般提示用户输入一些内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 输入输出</title>
</head>
<body>
  
  <script> 
    // 1. 输入的任意数字,都会以弹窗形式展示
    document.write('要输出的内容')
    alert('要输出的内容');

    // 2. 以弹窗形式提示用户输入姓名,注意这里的文字使用英文的引号
    prompt('请输入您的姓名:')
  </script>
</body>
</html>

例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      prompt('请输入')
    </script>
</body>
</html>

效果:

image-20241014210803345

变量

理解变量是计算机存储数据的“容器”,掌握变量的声明方式

变量是计算机中用来存储数据的“容器”,它可以让计算机变得有记忆,通俗的理解变量就是使用【某个符号】来代表【某个具体的数值】(数据)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<script>
  // x 符号代表了 5 这个数值
  x = 5
  // y 符号代表了 6 这个数值
  y = 6
    
  //举例: 在 JavaScript 中使用变量可以将某个数据(数值)记录下来!

  // 将用户输入的内容保存在 num 这个变量(容器)中
  num = prompt('请输入一数字!')

  // 通过 num 变量(容器)将用户输入的内容输出出来
  alert(num)
  document.write(num)
</script>

声明

声明(定义)变量有两部分构成:声明关键字、变量名(标识)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 声明和赋值</title>
</head>
<body>
  
  <script> 
    // let 变量名
    // 声明(定义)变量有两部分构成:声明关键字、变量名(标识)
    // let 即关键字,所谓关键字是系统提供的专门用来声明(定义)变量的词语
    // age 即变量的名称,也叫标识符
    let age
  </script>
</body>
</html>

关键字是 JavaScript 中内置的一些英文词汇(单词或缩写),它们代表某些特定的含义,如 let 的含义是声明变量的,看到 let 后就可想到这行代码的意思是在声明变量,如 let age;

letvar 都是 JavaScript 中的声明变量的关键字,推荐使用 let 声明变量!!!

赋值

声明(定义)变量相当于创造了一个空的“容器”,通过赋值向这个容器中添加数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 声明和赋值</title>
</head>
<body>
  
  <script> 
    // 声明(定义)变量有两部分构成:声明关键字、变量名(标识)
    // let 即关键字,所谓关键字是系统提供的专门用来声明(定义)变量的词语
    // age 即变量的名称,也叫标识符
    let age
    // 赋值,将 18 这个数据存入了 age 这个“容器”中
    age = 18
    // 这样 age 的值就成了 18
    document.write(age)
    
    // 也可以声明和赋值同时进行
    let str = 'hello world!'
    alert(str);
  </script>
</body>
</html>

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let temp = prompt('请输入')
      document.write(temp)
    </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-14 21-43-12.gif)

关键字

JavaScript 使用专门的关键字 letvar 来声明(定义)变量,在使用时需要注意一些细节:

以下是使用 let 时的注意事项:

  1. 允许声明和赋值同时进行
  2. 不允许重复声明
  3. 允许同时声明多个变量并赋值
  4. JavaScript 中内置的一些关键字不能被当做变量名

以下是使用 var 时的注意事项:

  1. 允许声明和赋值同时进行
  2. 允许重复声明
  3. 允许同时声明多个变量并赋值

大部分情况使用 letvar 区别不大,但是 let 相较 var 更严谨,因此推荐使用 let,后期会更进一步介绍二者间的区别。

变量名命名规则

关于变量的名称(标识符)有一系列的规则需要遵守:

  1. 只能是字母、数字、下划线_、$,且不能能数字开头
  2. 字母区分大小写,如 Age 和 age 是不同的变量
  3. JavaScript 内部已占用于单词(关键字或保留字)不允许使用
  4. 尽量保证变量具有一定的语义,见字知义

注:所谓关键字是指 JavaScript 内部使用的词语,如 letvar,保留字是指 JavaScript 内部目前没有使用的词语,但是将来可能会使用词语。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 变量名命名规则</title>
</head>
<body>
  
  <script> 
    let age = 18 // 正确
    let age1 = 18 // 正确
    let _age = 18 // 正确

    // let 1age = 18; // 错误,不可以数字开头
    let $age = 18 // 正确
    let Age = 24 // 正确,它与小写的 age 是不同的变量
    // let let = 18; // 错误,let 是关键字
    let int = 123 // 不推荐,int 是保留字
  </script>
</body>
</html>

数组

1.声明语法:let 数组名 = [数据1,数据2,……,数据n]

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let arr = ['小明', '小日', '小月', 1, 2, 3]
      document.write(arr)
      document.write('<br/>',arr[2])
    </script>
</body>
</html>

效果:

image-20241014230601104

2.数组长度:可以通过length属性获得

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let arr = ['小明','小日','小月',1,2,3]
      document.write(arr.length)
    </script>
</body>
</html>

效果:

image-20241014231535204

常量(const的声明)

概念:使用 const 声明的变量称为“常量”。

使用场景:当某个变量永远不会改变的时候,就可以使用 const 来声明,而不是let。

命名规范:和变量一致

1
const PI = 3.14

注意: 常量不允许重新赋值,声明的时候必须赋值(初始化)

补充:

在声明一些未来不太会被修改的变量时,一般使用const

对于复杂类型数据,比如数组一般可以使用const声明,因为此时栈中存放的是数组对象实例所在的地址,对该数组进行增加、删除或修改等操作时,数组依旧是原来的数组,地址并不会变,因此对数组进行增加、删除或修改等操作时并不会报错(但如果修改了数组的地址就会报错)

如下情况中,就可以把let改为const

image-20241020163119258

而下列左边的情况就不能用const,否则会报错

image-20241020163418281

数据类型

计算机世界中的万事成物都是数据。

计算机程序可以处理大量的数据,为了方便数据的管理,将数据分成了不同的类型:

number数字型、string字符串型、boolean布尔型、undefined未定义型、null空类型

注:通过 typeof 关键字检测数据类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 数据类型</title>
</head>
<body>
  
  <script> 
    // 检测 1 是什么类型数据,结果为 number
    document.write(typeof 1)
  </script>
</body>
</html>

数值类型

即我们数学中学习到的数字,可以是整数、小数、正数、负数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 数据类型</title>
</head>
<body>
  
  <script> 
    let score = 100 // 正整数
    let price = 12.345 // 小数
    let temperature = -40 // 负数

    document.write(typeof score) // 结果为 number
    document.write(typeof price) // 结果为 number
    document.write(typeof temperature) // 结果为 number
  </script>
</body>
</html>

JavaScript 中的数值类型与数学中的数字是一样的,分为正数、负数、小数等。

输入不符合规范的计算时,会输出NaN(Not a Number)

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let num = '你好' * 2
      document.write(num)
    </script>
</body>
</html>

效果:

image-20241015112501024

字符串类型

通过单引号( '') 、双引号( "")或反引号(``)包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。

注意事项:

  1. 无论单引号或是双引号必须成对使用
  2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已
  3. 必要时可以使用转义符 \,输出单引号或双引号
  4. prompt收集的数据默认是字符串
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 数据类型</title>
</head>
<body>
  
  <script> 
    let user_name = '小明' // 使用单引号
    let gender = "男" // 使用双引号
    let str = '123' // 看上去是数字,但是用引号包裹了就成了字符串了
    let str1 = '' // 这种情况叫空字符串
		
    documeent.write(typeof user_name) // 结果为 string
    documeent.write(typeof gender) // 结果为 string
    documeent.write(typeof str) // 结果为 string
  </script>
</body>
</html>

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let num1  = prompt('请输入一个数字')
      let num2  = prompt('请再输入一个数字')
      let sum = num1 + num2
      document.write(typeof num1)
      document.write(`<br>${typeof num2}`)
      document.write(`<br>两个数字相加等于${sum}`)
    </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-15 16-10-12.gif)

字符串的拼接

两个字符串可以用 + 来连接,字符串 + 数字会自动拼接成字符串

例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let myname = '我的' + '名字'
      document.write(myname) //输出:我的名字
    </script>
</body>
</html>

例2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let age = 18
      document.write('我今年' + age + '岁') //输出:我今年18岁
    </script>
</body>
</html>

模板字符串

使用场景:字符串的拼接,用+拼接字符串比较不方便,所以一般用模板字符串拼接变量

语法:最外面用反应号包裹``,用${}包住变量

例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let age = 18
      document.write(`我今年${age}岁`) //输出:我今年18岁
    </script>
</body>
</html>

例2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let name = prompt('名字')
      let age = prompt('年龄')
      document.write(`你的名字是:${name},年龄是${age}岁`)
    </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-15 13-20-18.gif)

布尔类型

表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 truefalse,表示肯定的数据用 true,表示否定的数据用 false

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 数据类型</title>
</head>
<body>
  <script> 
    //  pink老师帅不帅?回答 是 或 否
    let isCool = true // 是的,摔死了!
    isCool = false // 不,套马杆的汉子!

    document.write(typeof isCool) // 结果为 boolean
  </script>
</body>
</html>

undefined

未定义是比较特殊的类型,只有一个值 undefined,只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 数据类型</title>
</head>
<body>
  <script> 
    // 只声明了变量,并末赋值
    let tmp;
    document.write(typeof tmp) // 结果为 undefined
  </script>
</body>
</html>

注:JavaScript 中变量的值决定了变量的数据类型。

null

null仅仅是一个代表“无”、“空”或“值未知”的特殊值

null和undefined区别:

1.undefined表示没有赋值

2.null表示赋值了,但是内容为空

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      document.write(undefined + 1)//输出:NaN
      document.write(null + 1)//输出:1
    </script>
</body>
</html>

null开发中的使用场景:

把null作为尚未创建的对象(将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      let temp = null
      document.write(typeof temp)//输出:object
      document.write(temp)//输出:null
    </script>
</body>
</html>

类型转换

理解弱类型语言的特征,掌握显式类型转换的方法

在 JavaScript 中数据被分成了不同的类型,如数值、字符串、布尔值、undefined,在实际编程的过程中,不同数据类型之间存在着转换的关系。

隐式转换

某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。

规则:

  • +号两边只要有一个是字符串,都会把另外一个转成字符串
  • 除了+以外的算术运算符,比如 -*/ 等都会把数据转成数字类型
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 隐式转换</title>
</head>
<body>
  <script> 
    let num = 13 // 数值
    let num2 = '2' // 字符串

    // 结果为 132
    // 原因是将数值 num 转换成了字符串,相当于 '13'
    // 然后 + 将两个字符串拼接到了一起
    console.log(num + num2)

    // 结果为 11
    // 原因是将字符串 num2 转换成了数值,相当于 2
    // 然后数值 13 减去 数值 2
    console.log(num - num2)

    let a = prompt('请输入一个数字')
    let b = prompt('请再输入一个数字')

    alert(a + b);
  </script>
</body>
</html>

注:数据类型的隐式转换是 JavaScript 的特征,后续学习中还会遇到,目前先需要理解什么是隐式转换。

补充介绍模板字符串的拼接的使用

小技巧:

  • +号作为正号解析可以转换成数字型
  • 任何数据和字符串相加结果都是字符串
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
    <script>
      console.log(11 + 11)//22
      console.log('11' + 11)//1111
      console.log(11 - 11)//0
      console.log('11' - 11)//0
      console.log(1 * 1)//1
      console.log('1' * 1)//1
      console.log(typeof '123')//string
      console.log(typeof +'123')//number
      console.log(+'11' + 11)//22
    </script>
</body>
</html>

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let num1 = +prompt('请输入一个数字')
    let num2 = +prompt('请再输入一个数字')
    alert(`两数相加等于${num1 + num2}`)
  </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-15 16-36-22-1728981521569-4.gif)

显式转换

编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。

Number()

通过 Number 显示转换成数值类型,当转换失败时结果为 NaN(Not a Number)即不是一个数字。(NaN也是number类型的数据,代表非数字)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 隐式转换</title>
</head>
<body>
  <script>
    let t = '12'
    let f = 8

    // 显式将字符串 12 转换成数值 12
    t = Number(t)

    // 检测转换后的类型
    // console.log(typeof t);
    console.log(t + f) // 结果为 20

    // 并不是所有的值都可以被转成数值类型
    let str = 'hello'
    // 将 hello 转成数值是不现实的,当无法转换成
    // 数值时,得到的结果为 NaN (Not a Number)
    console.log(Number(str))
  </script>
</body>
</html>

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let num1 = Number(prompt('请输入一个数字'))
    let num2 = Number(prompt('请再输入一个数字'))
    alert(`两数相加等于${num1 + num2}`)
  </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-15 16-36-22.gif)

parseInt()

只保留整数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    console.log(parseInt('12px'))//输出:12
    console.log(parseInt('12.01px'))//输出:12
    console.log(parseInt('12.99px'))//输出:12
    console.log(parseInt('12.34px56'))//输出:12
  </script>
</body>
</html>
parseFloat()

可以保留小数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    console.log(parseFloat('12px'))//输出:12
    console.log(parseFloat('12.01px'))//输出:12.01
    console.log(parseFloat('12.99px'))//输出:12.99
    console.log(parseFloat('12.34px56'))//输出:12.34
  </script>
</body>
</html>
String()、变量.toString()

转化成字符串

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let temp = 123
    console.log(typeof temp)//number
    temp = String(temp)
    console.log(typeof temp)//string
    temp = 123
    console.log(typeof temp)//number
    temp = temp.toString()
    console.log(typeof temp)//string
  </script>
</body>
</html>

常见错误

1.

image-20241015172436292

2.

image-20241015172606382

3.

image-20241015172627989

4.

image-20241015172643750

5.

image-20241015172655991

综合案例

实现以下效果:

![](/assets/GIF 2024-10-15 17-21-32.gif)

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>综合1</title>
  <style>
    h2 {
      text-align: center;
    }
    table,th,td {
      margin: auto;
      border: 1px solid black;
    }
    table {
      /* 合并相邻边框 */
      border-collapse: collapse;
      height: 100px;
      text-align: center;
    }
    th,td {
      padding: 5px 30px;
    }
  </style>
</head>
<body>
  <h2>订单确认</h2>
  <script>
    let name = prompt('请输入商品名称:')
    let price = +prompt('请输入商品价格:')
    let num = +prompt('请输入商品数量:')
    let address = prompt('请输入收货地址')
    let sum = price * num   //总价
    document.write(`
      <table>
        <tr>
          <th>商品名称</th>
          <th>商品价格</th>
          <th>商品数量</th>
          <th>总价</th>
          <th>收货地址</th>
        </tr>
        <tr>
          <td>${name}</td>
          <td>${price}</td>
          <td>${num}</td>
          <td>${sum}</td>
          <td>${address}</td>
        </tr>
      </table>
    `)
  </script>
</body>
</html>

JavaScript 基础 - 第2天

理解什么是流程控制,知道条件控制的种类并掌握其对应的语法规则,具备利用循环编写简易ATM取款机程序能力

  • 运算符
  • 语句
  • 综合案例

运算符

算术运算符

数字是用来计算的,比如:乘法 * 、除法 / 、加法 + 、减法 - 等等,所以经常和算术运算符一起。

算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余(求模)等

运算符 作用
+ 求和
- 求差
* 求积
/ 求商
% 取模(取余数),开发中经常用于作为某个数字是否被整除

注意:在计算失败时,显示的结果是 NaN (not a number)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 算术运算符
console.log(1 + 2 * 3 / 2) //  4 
let num = 10
console.log(num + 10)  // 20
console.log(num + num)  // 20

// 1. 取模(取余数)  使用场景:  用来判断某个数是否能够被整除
console.log(4 % 2) //  0  
console.log(6 % 3) //  0
console.log(5 % 3) //  2
console.log(3 % 5) //  3

// 2. 注意事项 : 如果我们计算失败,则返回的结果是 NaN (not a number)
console.log('pink老师' - 2)
console.log('pink老师' * 2)
console.log('pink老师' + 2)   // pink老师2

赋值运算符

赋值运算符:对变量进行赋值的运算符

= 将等号右边的值赋予给左边, 要求左边必须是一个容器

运算符 作用
+= 加法赋值
-+ 减法赋值
*= 乘法赋值
/= 除法赋值
%= 取余赋值
1
2
3
4
5
6
7
8
<script>
let num = 1
// num = num + 1
// 采取赋值运算符
// num += 1
num += 3
console.log(num)
</script>

自增/自减运算符

符号 作用 说明
++ 自增 变量自身的值加1,例如: x++
自减 变量自身的值减1,例如: x–
  1. ++在前和++在后在单独使用时二者并没有差别,而且一般开发中我们都是独立使用
  2. ++在后(后缀式)我们会使用更多

注意:

  1. 只有变量能够使用自增和自减运算符
  2. ++、– 可以在变量前面也可以在变量后面,比如: x++ 或者 ++x
  3. 前置自增:先自加再使用
  4. 后置自增:先使用再自加
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
    // let num = 10
    // num = num + 1
    // num += 1
    // // 1. 前置自增
    // let i = 1
    // ++i
    // console.log(i)

    // let i = 1
    // console.log(++i + 1)//3
    // 2. 后置自增
    // let i = 1
    // i++
    // console.log(i)
    
    // let i = 1
    // console.log(i++ + 1)//输出2
    // console.log(i)//输出2

    // 了解
    let i = 1
    console.log(i++ + ++i + i)//7(1+3+3)
  </script>

image-20241015212546085

比较运算符

使用场景:比较两个数据大小、是否相等,根据比较结果返回一个布尔值(true / false)

运算符 作用
> 左边是否大于右边
< 左边是否小于右边
>= 左边是否大于或等于右边
<= 左边是否小于或等于右边
=== 左右两边是否类型都相等(重点)
== 左右两边是否相等
!= 左右值不相等
!== 左右两边是否不全等
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
  console.log(3 > 5)
  console.log(3 >= 3)
  console.log(2 == 2)
  // 比较运算符有隐式转换 把'2' 转换为 2  双等号 只判断值
  console.log(2 == '2')  // true
  // console.log(undefined === null) // false 
  // === 全等 判断 值 和 数据类型都一样才行
  // 以后判断是否相等 请用 ===  
  console.log(2 === '2') // false 
  console.log(NaN === NaN) // false(NaN 不等于任何人,包括他自己)
  console.log(2 !== '2')  // true  
  console.log(2 != '2') // false 
  console.log('-------------------------')
  //字符串依次比较字母的ASCII码,第一个字母和第一个字母比
  //若相同就依次往后比
  console.log('a' < 'b') // true
  console.log('aa' < 'ab') // true
  console.log('aa' < 'aac') // true
  console.log('-------------------------')
</script>

逻辑运算符

使用场景:可以把多个布尔值放到一起运算,最终返回一个布尔值

符号 名称 日常读法 特点 口诀
&& 逻辑与 并且 符号两边有一个假的结果为假 一假则假
|| 逻辑或 或者 符号两边有一个真的结果为真 一真则真
! 逻辑非 取反 true变false false变true 真变假,假变真
A B A && B A || B !A
false false false false true
false true false true true
true false false true false
true true true true false
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
    // 逻辑与 一假则假
    console.log(true && true)	//true
    console.log(false && true)	//false
    console.log(3 < 5 && 3 > 2)	//true
    console.log(3 < 5 && 3 < 2)	//false
    console.log('-----------------')
    // 逻辑或 一真则真
    console.log(true || true)	//true
    console.log(false || true)	//true
    console.log(false || false)	//false
    console.log('-----------------')
    // 逻辑非  取反
    console.log(!true)	//false
    console.log(!false)	//true

    console.log('-----------------')

    let num = 6
    console.log(num > 5 && num < 10)//true
    console.log('-----------------')
  </script>

练习:判断一个数是否能被4整除,但不能被100整除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let num = +prompt('判断这个数是否能被4整除,但不能被100整除')
    alert(num % 4 === 0 && num % 100 !== 0)
  </script>
</body>
</html>

运算符优先级

image-20241015214725364

逻辑运算符优先级: !> && > ||

语句

表达式和语句

67101792498

分支语句

分支语句可以根据条件判定真假,来选择性的执行想要的代码

分支语句包含:

  1. if分支语句(重点)
  2. 三元运算符
  3. switch语句
if 分支语句

语法:

1
2
3
if(条件表达式) {
  // 满足条件要执行的语句
}

小括号内的条件结果是布尔值,为 true 时,进入大括号里执行代码;为false,则不执行大括号里面代码

小括号内的结果若不是布尔类型时,会发生类型转换为布尔值,类似Boolean()

如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做~

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script>
    // 单分支语句
    // if (false) {
    //   console.log('执行语句')
    // }
    // if (3 > 5) {
    //   console.log('执行语句')
    // }
    // if (2 === '2') {
    //   console.log('执行语句')
    // }
    //  1. 除了0 所有的数字都为真
    //   if (0) {
    //     console.log('执行语句')
    //   }
    // 2.除了 '' 所有的字符串都为真 true
    // if ('pink老师') {
    //   console.log('执行语句')
    // }
    // if ('') {
    //   console.log('执行语句')
    // }
    // // if ('') console.log('执行语句')

    // 1. 用户输入
    let score = +prompt('请输入成绩')
    // 2. 进行判断输出
    if (score >= 700) {
      alert('恭喜考入黑马程序员')
    }
    console.log('-----------------')

  </script>
if双分支语句

如果有两个条件的时候,可以使用 if else 双分支语句

1
2
3
4
5
if (条件表达式){
  // 满足条件要执行的语句
} else {
  // 不满足条件要执行的语句
}

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 <script>
    // 1. 用户输入
    let uname = prompt('请输入用户名:')
    let pwd = prompt('请输入密码:')
    // 2. 判断输出
    if (uname === 'pink' && pwd === '123456') {
      alert('恭喜登录成功')
    } else {
      alert('用户名或者密码错误')
    }
  </script>
if 多分支语句

使用场景: 适合于有多个条件的时候

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 <script>
    // 1. 用户输入
    let score = +prompt('请输入成绩:')
    // 2. 判断输出
    if (score >= 90) {
      alert('成绩优秀,宝贝,你是我的骄傲')
    } else if (score >= 70) {
      alert('成绩良好,宝贝,你要加油哦~~')
    } else if (score >= 60) {
      alert('成绩及格,宝贝,你很危险~')
    } else {
      alert('成绩不及格,宝贝,我不想和你说话,我只想用鞭子和你说话~')
    }
  </script>
三元运算符(三元表达式)

使用场景: 一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 if else双分支 更简单

符号:? 与 : 配合使用

语法:

1
条件 ? 表达式1  表达式2

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 三元运算符(三元表达式)
// 1. 语法格式
// 条件 ? 表达式1 : 表达式2 

// 2. 执行过程 
// 2.1 如果条件为真,则执行表达式1
// 2.2 如果条件为假,则执行表达式2

// 3. 验证
// 5 > 3 ? '真的' : '假的'
console.log(5 < 3 ? '真的' : '假的')

// let age = 18 
// age = age + 1
//  age++

// 1. 用户输入 
let num = prompt('请您输入一个数字:')
// 2. 判断输出- 小于10才补0
// num = num < 10 ? 0 + num : num
num = num >= 10 ? num : 0 + num
alert(num)
switch语句(了解)

使用场景: 适合于有多个条件的时候,也属于分支语句,大部分情况下和 if多分支语句 功能相同

注意:

  1. switch case语句一般用于等值判断, if适合于区间判断
  2. switchcase一般需要配合break关键字使用 没有break会造成case穿透
  3. if 多分支语句开发要比switch更重要,使用也更多

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// switch分支语句
// 1. 语法
// switch (表达式) {
//   case 值1:
//     代码1
//     break

//   case 值2:
//     代码2
//     break
//   ...
//   default:
//     代码n
// }

<script>
  switch (2) {
    case 1:
    console.log('您选择的是1')
    break  // 退出switch
    case 2:
    console.log('您选择的是2')
    break  // 退出switch
    case 3:
    console.log('您选择的是3')
    break  // 退出switch
    default:
    console.log('没有符合条件的')
  }
</script>

练习:输入两个数和+-*/中的一个符号,并输出结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let num1 = +prompt('请输入一个数')
    let num2 = +prompt('请再输入一个数')
    let sp = prompt('请输入运算符号')
    switch (sp) {
      case '+':
        alert(`${num1 + sp + num2}结果是${num1 + num2}`)
        break
      case '-':
        alert(`${num1 + sp + num2}结果是${num1 - num2}`)
        break
      case '*':
        alert(`${num1 + sp + num2}结果是${num1 * num2}`)
        break
      case '/':
        alert(`${num1 + sp + num2}结果是${num1 / num2}`)
        break
      default:
        alert('请从+-*/中选一个符号')
    }
  </script>
</body>
</html>
断点调试

**作用:**学习时可以帮助更好的理解代码运行,工作时可以更快找到bug

浏览器打开调试界面

  1. 按F12打开开发者工具
  2. 点到源代码一栏 ( sources )
  3. 选择代码文件

**断点:**在某句代码上加的标记就叫断点,当程序执行到这句有标记的代码时会暂停下来

![](/assets/GIF 2024-10-15 23-24-39.gif)

循环语句

使用场景:重复执行 指定的一段代码,比如我们想要输出10次 ‘我学的很棒’

学习路径:

1.while循环

2.for 循环(重点)

while循环

while : 在…. 期间, 所以 while循环 就是在满足条件期间,重复执行某些代码。

语法:

1
2
3
while (条件表达式) {
   // 循环体    
}

例如:

1
2
3
4
5
6
7
8
// while循环: 重复执行代码

// 1. 需求: 利用循环重复打印3次 '月薪过万不是梦,毕业时候见英雄'
let i = 1
while (i <= 3) {
  document.write('月薪过万不是梦,毕业时候见英雄~<br>')
  i++   // 这里千万不要忘了变量自增否则造成死循环
}

循环三要素:

1.初始值 (经常用变量)

2.终止条件

3.变量的变化量

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<script>
  // // 1. 变量的起始值
  // let i = 1
  // // 2. 终止条件
  // while (i <= 3) {
  //   document.write('我要循环三次 <br>')
  //   // 3. 变量的变化量
  //   i++
  // }
  // 1. 变量的起始值
  let end = +prompt('请输入次数:')
let i = 1
// 2. 终止条件
while (i <= end) {
  document.write('我要循环三次 <br>')
  // 3. 变量的变化量
  i++
}

</script>
中止循环

break 中止整个循环,一般用于结果已经得到, 后续的循环不需要的时候可以使用(提高效率)

continue 中止本次循环,一般用于排除或者跳过某一个选项的时候

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
    // let i = 1
    // while (i <= 5) {
    //   console.log(i)
    //   if (i === 3) {
    //     break  // 退出循环
    //   }
    //   i++

    // }


    let i = 1
    while (i <= 5) {
      if (i === 3) {
        i++
        continue
      }
      console.log(i)
      i++

    }
  </script>
无限循环

1.while(true) 来构造“无限”循环,需要使用break退出循环。(常用)

2.for(;;) 也可以来构造“无限”循环,同样需要使用break退出循环。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 无限循环  
// 需求: 页面会一直弹窗询问你爱我吗?
// (1). 如果用户输入的是 '爱',则退出弹窗
// (2). 否则一直弹窗询问

// 1. while(true) 无限循环
// while (true) {
//   let love = prompt('你爱我吗?')
//   if (love === '爱') {
//     break
//   }
// }

// 2. for(;;) 无限循环
for (; ;) {
  let love = prompt('你爱我吗?')
  if (love === '爱') {
    break
  }
}
练习

计算1-100之间的所有偶数和

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let i = 1
    let sum = 0
    while (i <= 100) {
      if (i % 2 === 0) {
        sum += i
      }
      i++
    }
    document.write(sum)//2550
  </script>
</body>
</html>

综合案例-ATM存取款机

67101878155

分析:

①:提示输入框写到循环里面(无限循环)

②:用户输入4则退出循环 break

③:提前准备一个金额预先存储一个数额 money

④:根据输入不同的值,做不同的操作

​ (1) 取钱则是减法操作, 存钱则是加法操作,查看余额则是直接显示金额

​ (2) 可以使用 if else if 多分支 来执行不同的操作

完整代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script>
  // 1. 开始循环 输入框写到 循环里面
  // 3. 准备一个总的金额
  let money = 100
while (true) {
  let re = +prompt(`
请您选择操作:
1.存钱
2.取钱
3.查看余额
4.退出
`)
  // 2. 如果用户输入的 4 则退出循环, break  写到if 里面,没有写到switch里面, 因为4需要break退出循环
  if (re === 4) {
    break
  }
  // 4. 根据输入做操作
  switch (re) {
    case 1:
      // 存钱
      let cun = +prompt('请输入存款金额')
      money = money + cun
      break
      case 2:
      // 存钱
      let qu = +prompt('请输入取款金额')
      money = money - qu
      break
      case 3:
      // 存钱
      alert(`您的银行卡余额是${money}`)
      break
  }
}
</script>

我自己写的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let event
    let money = 0
    while(event !== '退出') {
      event = prompt(`
      请输入要进行的操作
      1.存钱
      2.取钱
      3.查询余额
      4.退出
      `)
      switch (event) {
      case '存钱':
        money += +prompt('请输入要存入金额')
        break
      case '取钱':
        money -= +prompt('请输入要取出金额')
        break
      case '查询余额':
        alert(`当前余额为${money}元`)
        break
      case '退出':
        break;
      default:
        alert('请输入正确操作!')
      }
    }
  </script>
</body>
</html>

JavaScript 基础第三天笔记

if 多分支语句和 switch的区别:

  1. 共同点

    • 都能实现多分支选择, 多选1
    • 大部分情况下可以互换
  2. 区别:

    • switch…case语句通常处理case为比较确定值的情况,而if…else…语句更加灵活,通常用于范围判断(大于,等于某个范围)。
    • switch 语句进行判断后直接执行到程序的语句,效率更高,而if…else语句有几种判断条件,就得判断多少次
    • switch 一定要注意 必须是 === 全等,一定注意 数据类型,同时注意break否则会有穿透效果
    • 结论:
      • 当分支比较少时,if…else语句执行效率高。
      • 当分支比较多时,switch语句执行效率高,而且结构更清晰。

for 语句

掌握 for 循环语句,让程序具备重复执行能力

for 是 JavaScript 提供的另一种循环控制的话句,它和 while 只是语法上存在差异。

for语句的基本使用

  1. 实现循环的 3 要素
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<script>
  // 1. 语法格式
  // for(起始值; 终止条件; 变化量) {
  //   // 要重复执行的代码
  // }

  // 2. 示例:在网页中输入标题标签
  // 起始值为 1
  // 变化量 i++
  // 终止条件 i <= 6
  for(let i = 1; i <= 6; i++) {
    document.write(`<h${i}>循环控制,即重复执行<h${i}>`)
  }
</script>
  1. 变化量和死循环,for 循环和 while 一样,如果不合理设置增量和终止条件,便会产生死循环。

  2. 跳出和终止循环

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<script>
    // 1. continue 
    for (let i = 1; i <= 5; i++) {
        if (i === 3) {
            continue  // 结束本次循环,继续下一次循环
        }
        console.log(i)
    }
    // 2. break
    for (let i = 1; i <= 5; i++) {
        if (i === 3) {
            break  // 退出结束整个循环
        }
        console.log(i)
    }
</script>

结论:

  • JavaScript 提供了多种语句来实现循环控制,但无论使用哪种语句都离不开循环的3个特征,即起始值、变化量、终止条件,做为初学者应着重体会这3个特征,不必过多纠结三种语句的区别。
  • 起始值、变化量、终止条件,由开发者根据逻辑需要进行设计,规避死循环的发生。
  • 当如果明确了循环的次数的时候推荐使用for循环,当不明确循环的次数的时候推荐使用while循环

注意:for 的语法结构更简洁,故 for 循环的使用频次会更多。

练习

遍历数组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let arr = ['小米', '小哈', '小游', '小原', '小铁']
    for(let i = 0; i < arr.length; i++) {
      document.write(arr[i] + '<br>')
    }
  </script>
</body>
</html>

效果:

image-20241016220831593

循环嵌套

利用循环的知识来对比一个简单的天文知识,我们知道地球在自转的同时也在围绕太阳公转,如果把自转和公转都看成是循环的话,就相当于是循环中又嵌套了另一个循环。

universe

实际上 JavaScript 中任何一种循环语句都支持循环的嵌套,如下代码所示:

64791826139

1
2
3
4
5
6
7
8
// 1. 外面的循环 记录第n天 
for (let i = 1; i < 4; i++) {
    document.write(`${i} <br>`)
    // 2. 里层的循环记录 几个单词
    for (let j = 1; j < 6; j++) {
        document.write(`记住第${j}个单词<br>`)
    }
}

记住,外层循环循环一次,里层循环循环全部

例:每天背5个单词,一共背三天

要求效果:

image-20241016222852441

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    for (let i = 1; i <= 3; i++) {
      document.write(`第${i}天<br>`)
      for (let j = 1;j <= 5; j++) {
        document.write(`记住今天第${j}个单词<br>`)
      }
    }
  </script>
</body>
</html>
倒三角
1
2
3
4
5
6
7
8
 // 外层打印几行
for (let i = 1; i <= 5; i++) {
    // 里层打印几个星星
    for (let j = 1; j <= i; j++) {
        document.write('★')
    }
    document.write('<br>')
}

64791867895

九九乘法表

样式css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
span {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    border: 1px solid pink;
    margin: 2px;
    border-radius: 5px;
    box-shadow: 2px 2px 2px rgba(255, 192, 203, .4);
    background-color: rgba(255, 192, 203, .1);
    text-align: center;
    color: hotpink;
}

javascript

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 // 外层打印几行
for (let i = 1; i <= 9; i++) {
    // 里层打印几个星星
    for (let j = 1; j <= i; j++) {
        // 只需要吧 ★ 换成  1 x 1 = 1   
        document.write(`
		<span> ${j} x ${i} = ${j * i} </span>
     `)
    }
    document.write('<br>')
}

64791873467

数组

知道什么是数组及其应用的场景,掌握数组声明及访问的语法。

数组是什么?

数组:(Array)是一种可以按顺序保存数据的数据类型

**使用场景:**如果有多个数据可以用数组保存起来,然后放到一个变量中,管理非常方便

数组的基本使用

定义数组和数组单元
1
2
3
4
5
6
7
8
<script>
  // 1. 语法,使用 [] 来定义一个空数组
  // 定义一个空数组,然后赋值给变量 classes
  // let classes = [];

  // 2. 定义非空数组
  let classes = ['小明', '小刚', '小红', '小丽', '小米']
</script>

通过 [] 定义数组,数据中可以存放真正的数据,如小明、小刚、小红等这些都是数组中的数据,我们这些数据称为数组单元,数组单元之间使用英文逗号分隔。

访问数组和数组索引

使用数组存放数据并不是最终目的,关键是能够随时的访问到数组中的数据(单元)。其实 JavaScript 为数组中的每一个数据单元都编了号,通过数据单元在数组中的编号便可以轻松访问到数组中的数据单元了。

我们将数据单元在数组中的编号称为索引值,也有人称其为下标。

索引值实际是按着数据单元在数组中的位置依次排列的,注意是从 0 开始的,如下图所示:

array

观察上图可以数据单元【小明】对应的索引值为【0】,数据单元【小红】对应的索引值为【2】

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<script>
  let classes = ['小明', '小刚', '小红', '小丽', '小米']
  
  // 1. 访问数组,语法格式为:变量名[索引值]
  document.write(classes[0]) // 结果为:小明
  document.write(classes[1]) // 结果为:小刚
  document.write(classes[4]) // 结果为:小米
  
  // 2. 通过索引值还可以为数组单重新赋值
  document.write(classes[3]) // 结果为:小丽
  // 重新为索引值为 3 的单元赋值
  classes[3] = '小小丽'
  document.wirte(classes[3]); // 结果为: 小小丽
</script>
数据单元值类型

数组做为数据的集合,它的单元值可以是任意数据类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<script>
  // 6. 数组单值类型可以是任意数据类型

  // a) 数组单元值的类型为字符类型
  let list = ['HTML', 'CSS', 'JavaScript']
  // b) 数组单元值的类型为数值类型
  let scores = [78, 84, 70, 62, 75]
  // c) 混合多种类型
  let mixin = [true, 1, false, 'hello']
</script>
数组长度属性

重申一次,数组在 JavaScript 中并不是新的数据类型,它属于对象类型。

1
2
3
4
5
6
<script>
  // 定义一个数组
  let arr = ['html', 'css', 'javascript']
  // 数组对应着一个 length 属性,它的含义是获取数组的长度
  console.log(arr.length) // 3
</script>
练习:求数组最大值与最小值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let arr = [12, 23, 6, 18, 77, 11, 56, 1]
    let max = arr[0]
    let min = arr[0]
    let i = 1
    while (i < arr.length) {
      max = max > arr[i] ? max : arr[i]
      min = min < arr[i] ? min : arr[i]
      i++
    }
    document.write(`最小值是${min}<br>最大值是${max}`)
  </script>
</body>
</html>

效果:

image-20241016233024240

操作数组

数组做为对象数据类型,不但有 length 属性可以使用,还提供了许多方法:

  1. push 动态向数组的尾部添加一个单元
  2. unshit 动态向数组头部添加一个单元
  3. pop 删除最后一个单元
  4. shift 删除第一个单元
  5. splice 动态删除或增加任意单元

使用以上4个方法时,都是直接在原数组上进行操作,即成功调任何一个方法,原数组都跟着发生相应的改变。并且在添加或删除单元时 length 并不会发生错乱。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<script>
  // 定义一个数组
  let arr = ['html', 'css', 'javascript']

  // 1. push 动态向数组的尾部添加一个单元
  arr.push('Nodejs')
  console.log(arr)
  arr.push('Vue')

  // 2. unshit 动态向数组头部添加一个单元
  arr.unshift('VS Code')
  console.log(arr)

  // 3. splice 动态删除和增加任意单元
  arr.splice(2, 1) // 从索引值为2的位置开始删除1个单元
  console.log(arr)
    
  let arr = ['red', 'green', 'blue']
  arr.splice(1, 0, 'pink') // 在索引号是1的位置添加 pink
  console.log(arr) // ['red', 'pink', 'green', 'blue']
  arr.splice(1, 0, 'pink', 'hotpink') // 在索引号是1的位置添加 pink  hotpink
  console.log(arr) // ['red', 'pink', 'hotpink', 'green', 'blue']

  // 4. pop 删除最后一个单元
  arr.pop()
  console.log(arr)

  // 5. shift 删除第一个单元
  arr.shift()
  console.log(arr)
</script>

注:直接输出上述方法的效果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let arr = ['小米', '小哈', '小游']
    
    document.write(arr.push('小绝'))	   //4
    document.write(arr)					//小米,小哈,小游,小绝
      
    document.write(arr.unshift('小原'))  //5
    document.write(arr)					//小原,小米,小哈,小游,小绝
      
    document.write(arr.shift())			//小原
    document.write(arr)					//小米,小哈,小游,小绝
      
    document.write(arr.pop())			//小绝
    document.write(arr)					//小米,小哈,小游
      
    document.write(arr.splice(1,2))		//小哈,小游
    document.write(arr)					//小米
  </script>
</body>
</html>
数组的筛选

需求:将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组

分析:

①:声明一个新的数组用于存放新数据newArr

②:遍历原来的旧数组, 找出大于等于 10 的元素

③:依次追加给新数组 newArr

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]
    let newArr = []
    // 遍历旧数组
    for (let i = 0; i < arr.length; i++) {
      // 满足条件的存入新数组
      if (arr[i] >= 10) {
        newArr.push(arr[i])
      }
    }
    document.write(newArr)
  </script>
</body>
</html>

综合案例

需求:输入数据形成柱形图,如图

![](/assets/GIF 2024-10-17 13-31-43.gif)

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>综合案例2</title>
  <style>
    .outer {
      width: 800px;
      border-bottom: 2px solid black;
      border-left: 2px solid black;
      margin: auto;
      margin-top: 80px;
      display: flex;
      justify-content: space-around;
      align-items: flex-end;
    }
    .inner {
      width: 100px;
      background-color: pink;
      display: flex;
      justify-content: space-between;
      flex-direction: column;
      text-align: center;
    }
    .inner .data {
      position: relative;
      font-size: 20px;
      top: -30px;
    }
    .inner .quarter {
      position: relative;
      font-size: 25px;
      font-weight: bold;
      bottom: -50px;
    }
  </style>
</head>
<body>
  <script>
    // 获取每个季度的数据
    let arrData = []
    for (let i = 1; i <= 4; i++) {
      arrData.push(prompt(`请输入第${i}季度的数据`))
    }
    // 打印最外面的盒子的头
    document.write('<div class="outer">')
    // 通过循环打印中间重复的内容
    for (let i = 0; i < arrData.length; i++) {
      document.write(`
        <div class="inner">
        <span class="data" style="height: ${arrData[i]}px;">${arrData[i]}</span>
        <span class="quarter">第${i+1}季度</span>
      </div>
      `)
    }
    // 打印最外面盒子的尾
    document.write('</div>')
  </script>
</body>
</html>

JavaScript 基础 - 第4天笔记

理解封装的意义,能够通过函数的声明实现逻辑的封装,知道对象数据类型的特征,结合数学对象实现简单计算功能。

  • 理解函数的封装的特征
  • 掌握函数声明的语法
  • 理解什么是函数的返回值
  • 知道并能使用常见的内置函数

函数

理解函数的封装特性,掌握函数的语法规则

声明和调用

函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。

声明(定义)

声明(定义)一个完整函数包括关键字、函数名、形式参数、函数体、返回值5个部分

function

调用

声明(定义)的函数必须调用才会真正被执行,使用 () 调用函数。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 声明和调用</title>
</head>
<body>
  <script>
    // 声明(定义)了最简单的函数,既没有形式参数,也没有返回值
    function sayHi() {
      console.log('嗨~')
    }
    // 函数调用,这些函数体内的代码逻辑会被执行
    // 函数名()
        
    sayHi()
    // 可以重复被调用,多少次都可以
    sayHi()
  </script>
</body>
</html>

注:函数名的命名规则与变量是一致的,并且尽量保证函数名的语义。

小案例: 小星星

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
        // 函数声明
        function sayHi() {
            // document.write('hai~')
            document.write(`*<br>`)
            document.write(`**<br>`)
            document.write(`***<br>`)
            document.write(`****<br>`)
            document.write(`*****<br>`)
            document.write(`******<br>`)
            document.write(`*******<br>`)
            document.write(`********<br>`)
            document.write(`*********<br>`)
        }
        // 函数调用
        sayHi()
        sayHi()
        sayHi()
        sayHi()
        sayHi()
    </script>

参数

通过向函数传递参数,可以让函数更加灵活多变,参数可以理解成是一个变量。

声明(定义)一个功能为打招呼的函数

  • 传入数据列表
  • 声明这个函数需要传入几个数据
  • 多个数据用逗号隔开
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 函数参数</title>
</head>
<body>

  <script>
    // 声明(定义)一个功能为打招呼的函数
    // function sayHi() {
    //   console.log('嗨~')
    // }
    // 调用函数
    // sayHi()
	

    // 这个函数似乎没有什么价值,除非能够向不同的人打招呼
    // 这就需要借助参数来实现了
    function sayHi(name) {
      // 参数 name 可以被理解成是一个变量
      console.log(name)
      console.log('嗨~' + name)
    }

    // 调用 sayHi 函数,括号中多了 '小明'
    // 这时相当于为参数 name 赋值了
    sayHi('小明')// 结果为 小明

    // 再次调用 sayHi 函数,括号中多了 '小红'
    // 这时相当于为参数 name 赋值了
    sayHi('小红') // 结果为 小红
  </script>
</body>
</html>

总结:

  1. 声明(定义)函数时的形参没有数量限制,当有多个形参时使用 , 分隔
  2. 调用函数传递的实参要与形参的顺序一致
形参和实参

形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)

实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)

形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值

开发中尽量保持形参和实参个数一致

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 函数参数</title>
</head>
<body>
  <script>
    // 声明(定义)一个计算任意两数字和的函数
    // 形参 x 和 y 分别表示任意两个数字,它们是两个变量
    function count(x, y) {
      console.log(x + y);
    }
    // 调用函数,传入两个具体的数字做为实参
    // 此时 10 赋值给了形参 x
    // 此时 5  赋值给了形参 y
    count(10, 5); // 结果为 15
  </script>
</body>
</html>
默认参数

如果形参没有默认值,用户又没输入实参,可能会导致实际结果与预期不同,如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function getSum(a, b) {
      document.write(a + b)
    }
    getSum()  //NaN
  </script>
</body>
</html>

从生活上来说,两个空的数相加应该是0,但因为没有给入实参,a和b都undefined型,所以两者相加等于NaN

为了防止用户不输入实参,可以给 形参默认值,这样程序更严谨,形参有默认值时,并不影响实参的传入,如下

例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function getSum(a = 0, b = 0) {
      document.write(a + b)
    }
    getSum()      //0
    getSum(2, 6)  //8
  </script>
</body>
</html>

例2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function getArrSum(arr = []) {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      console.log(sum)
    }
    getArrSum([1,2,3])//6
    getArrSum()       //0(不设默认值会报错)
  </script>
</body>
</html>

说明:这个默认值只会在缺少实参参数传递时 才会被执行,所以有参数会优先执行传递过来的实参, 否则默认为undefined

返回值

函数的本质是封装(包裹),函数体内的逻辑执行完毕后,函数外部如何获得函数内部的执行结果呢?要想获得函数内部逻辑的执行结果,需要通过 return 这个关键字,将内部执行结果传递到函数外部,这个被传递到外部的结果就是返回值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 函数返回值</title>
</head>
<body>

  <script>
    // 定义求和函数
    function count(a, b) {
      let s = a + b
      // s 即为 a + b 的结果
      // 通过 return 将 s 传递到外部
      return s
    }

    // 调用函数,如果一个函数有返回值
    // 那么可将这个返回值赋值给外部的任意变量
    let total = count(5, 12)
  </script>
</body>
</html>

总结:

  • 在函数体中使用return 关键字能将内部的执行结果交给函数外部使用
  • 函数内部只能出现1 次 return,并且 return 下一行代码不会再被执行,所以return 后面的数据不要换行写
  • return会立即结束当前函数
  • 函数可以没有return,这种情况默认返回值为 undefined
返回多个值

当需要return多个值时,可以使用数组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    // 写一个求最大值和最小值的函数
    function getMaxAndMin(arr = []) {
      let max = arr[0]
      let min = arr[0]
      for (let i = 1; i < arr.length; i++) {
        max = max > arr[i] ? max : arr[i]
        min = min < arr[i] ? min : arr[i]
      }
      return [max, min]
    }
    let arrMaxAndMin = getMaxAndMin([1, 3, 5, 7, 9, 0])
    document.write(arrMaxAndMin)//9,0
  </script>
</body>
</html>
断点进入函数

在浏览器断点调试时,按F10可以下一步,而按F11也是下一步,但F10不会进入函数,F11可以进入函数,更细致地调试

![](/assets/GIF 2024-10-17 21-40-00.gif)

函数细节补充

在Javascript中 实参的个数和形参的个数可以不一致

  • 如果形参过多 会自动填上undefined
  • 如果实参过多 那么多余的实参会被忽略 (函数内部有一个arguments,里面装着所有的实参)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function getSum(a, b) {
      return a + b
    }
    // 实参多于形参
    document.write(getSum(1, 2, 100))//3
    // 实参少于形参
    document.write(getSum(1))		//NaN
  </script>
</body>
</html>

作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

全局作用域

作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件

处于全局作用域内的变量,称为全局变量

局部作用域

作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。

处于局部作用域内的变量称为局部变量

如果函数内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐

但是有一种情况,函数内部的形参可以看做是局部变量。

变量的访问原则

就近原则:在能够访问到的情况下,先局部,局部没有再找全局

例1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let temp = 10
    function getNum() {
      let sum = 20
      console.log(sum)
    }
    getNum()//20
  </script>
</body>
</html>

例2:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    function f1() {
      let num = 123
      function f2() {
        console.log(num)        
      }
      f2()
    }
    let num = 456
    f1()  //123
  </script>
</body>
</html>

例3:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
      function f1() {
        let num = 123
        function f2() {
          let num = 0
          console.log(num)
        }
        f2()
      }
      let num = 456
      f1() //0
  </script>
</body>
</html>

例4:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let a = 1
    function fn1() {
      let a = 2
      let b = '22'
      fn2()
      function fn2() {
        let a = 3
        fn3()
        function fn3() {
          let a = 4
          console.log(a) //4
          console.log(b) //22
        }
      }
    }
    fn1()
  </script>
</body>
</html>

匿名函数

函数可以分为具名函数和匿名函数

匿名函数:没有名字的函数,无法直接使用。

函数表达式
1
2
3
4
5
6
// 声明
let fn = function() { 
   console.log('函数表达式')
}
// 调用
fn()

函数表达式和具名函数的区别

具名函数的调用可以写到任意位置,就算是把调用写在声明之前也能正常运行,但函数表达式如果把调用写在声明之前就会报错

立即执行函数
1
2
(function(){ xxx  })();	//写法一
(function(){xxxx}());	//写法二

无需调用,立即执行,其实本质已经调用了

多个立即执行函数之间用分号隔开

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
     //写法一
    (function(x, y) {
      console.log(x + y)      
    })(1, 2);	//3
     //写法二
    (function(x, y) {
      console.log(x + y)      
    }(1, 2))	//3
  </script>
</body>
</html>

逻辑中断

image-20241017234714751

逻辑运算符里的短路

短路:只存在于 && 和 || 中,当满足一定条件会让右边代码不执行

image-20241017233934337

原因:通过左边能得到整个式子的结果,因此没必要再判断右边

运算结果:无论 && 还是 || ,运算结果都是最后被执行的表达式值,一般用在变量赋值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let age = 18
    console.log(false && age++)//false
    console.log(0 && age++)    //0
    console.log(age)           //18

    console.log(true || age++) //true
    console.log(1 || age++)    //1
    console.log(age)           //18

    console.log(11 && 22)      //22(逻辑与,都是真则返回最后一个真值)
    console.log(11 || 22)      //11(逻辑或,都是真则返回第一个真值,一真则真)
    
    console.log(undefined && 0)//undefined(逻辑与,遇到一个假直接返回,一假则假)
    console.log(undefined || 0)//0(逻辑或,都是假则返回最后一个)
  </script>
</body>
</html>

小练习:

image-20241017235942641

转换为布尔型

记忆‘’ 、0、undefined、null、false、NaN 转换为布尔值后都是false, 其余则为 true

隐式转换:

  1. 有字符串的加法 “” + 1 ,结果是 “1”
  2. 减法 - (像大多数数学运算一样)只能用于数字,它会使空字符串 "" 转换为 0
  3. null 经过数字转换之后会变为 0
  4. undefined 经过数字转换之后会变为 NaN

image-20241018000334386

image-20241018000351862

综合案例

需求:用户输入秒数,可以自动转换为几时几分几秒

分析:

①: 用户输入总秒数 (注意默认值)

②:计算时分秒(封装函数) 里面包含数字补0

③:打印输出

计算公式:计算时分秒

小时: h = parseInt(总秒数 / 60 / 60 % 24)

分钟: m = parseInt(总秒数 / 60 % 60 )

秒数: s = parseInt(总秒数 % 60)

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>综合3</title>
</head>
<body>
  <script>
    let second = +prompt('请输入秒数:')
    function getTime(t) {
      let h = parseInt(t / 60 / 60 % 24)
      let m = parseInt(t / 60 % 60 )
      let s = parseInt(t % 60)
      h = h < 10 ? '0' + h : h
      m = m < 10 ? '0' + m : m
      s = s < 10 ? '0' + s : s
      document.write(`${second}秒是${h}${m}${s}秒`)
    }
    getTime(second)
  </script>
</body>
</html>

效果:

![](/assets/GIF 2024-10-17 23-30-16.gif)

JavaScript 基础 - 第5天

知道对象数据类型的特征,能够利用数组对象渲染页面

  • 理解什么是对象,掌握定义对象的语法
  • 掌握数学对象的使用

对象

对象是 JavaScript 数据类型的一种,之前已经学习了数值类型、字符串类型、布尔类型、undefined。对象数据类型可以被理解成是一种数据集合。它由属性和方法两部分构成。

语法

声明一个对象类型的变量与之前声明一个数值或字符串类型的变量没有本质上的区别。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象语法</title>
</head>
<body>

  <script>
    // 声明字符串类型变量
    let str = 'hello world!'
    
    // 声明数值类型变量
    let num = 199

    // 声明对象类型变量,使用一对花括号
    // user 便是一个对象了,目前它是一个空对象
    let user = {}
  </script>
</body>
</html>

属性和访问

数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。

  1. 属性都是成 对出现的,包括属性名和值,它们之间使用英文 : 分隔
  2. 多个属性之间使用英文 , 分隔
  3. 属性就是依附在对象上的变量
  4. 属性名可以使用 ""'',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象语法</title>
</head>
<body>

  <script>
    // 通过对象描述一个人的数据信息
    // person 是一个对象,它包含了一个属性 name
    // 属性都是成对出现的,属性名 和 值,它们之间使用英文 : 分隔
    let person = {
      name: '小明', // 描述人的姓名
      age: 18, // 描述人的年龄
      stature: 185, // 描述人的身高
      gender: '男', // 描述人的性别
    }
  </script>
</body>
</html>

声明对象,并添加了若干属性后,可以使用 .[] 获得对象中属性对应的值,我称之为属性访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象语法</title>
</head>
<body>

  <script>
    // 通过对象描述一个人的数据信息
    // person 是一个对象,它包含了一个属性 name
    // 属性都是成对出现的,属性名 和 值,它们之间使用英文 : 分隔
    let person = {
      name: '小明', // 描述人的姓名
      age: 18, // 描述人的年龄
      stature: 185, // 描述人的身高
      gender: '男', // 描述人的性别
    };
    
    // 访问人的名字
    console.log(person.name) // 结果为 小明
    // 访问人性别
    console.log(person.gender) // 结果为 男
    // 访问人的身高
    console.log(person['stature']) // 结果为 185
   // 或者
    console.log(person.stature) // 结果同为 185
  </script>
</body>
</html>

扩展:也可以动态为对象添加属性,动态添加与直接定义是一样的,只是语法上更灵活。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象语法</title>
</head>
<body>

  <script>
    // 声明一个空的对象(没有任何属性)
	let user = {}
    // 动态追加属性
    user.name = '小明'
    user['age'] = 18
    
    // 动态添加与直接定义是一样的,只是语法上更灵活
  </script>
</body>
</html>

删除属性用delete

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let obj = {
      name: '张三',
    }
    document.write(obj.name)//张三
    delete obj.name
    document.write(obj.name)//undefined
  </script>
</body>
</html>

声明复杂属性名,即要使用特殊符号时就需要用 " " ''包裹起来

两种查的方式:

  1. 对象名.属性名
  2. 对象名[‘属性名’]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let obj = {
      // my-name: '张三'   //不能直接用-,不然会报错
      'my-name': '张三'
    }
    //document.write(obj.my-name)//此时就不能用这种方式访问
    document.write(obj['my-name'])//输出 张三
  </script>
</body>
</html>

方法和调用

数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数。

  1. 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
  2. 多个属性之间使用英文 , 分隔
  3. 方法是依附在对象中的函数
  4. 方法名可以使用 ""'',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象方法</title>
</head>
<body>

  <script>
    // 方法是依附在对象上的函数
    let person = {
      name: '小红',
      age: 18,
      // 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
      singing: function () {
        console.log('两只老虎,两只老虎,跑的快,跑的快...')
      },
      run: function () {
        console.log('我跑的非常快...')
      }
    }
  </script>
</body>
</html>

声明对象,并添加了若干方法后,可以使用 .[] 调用对象中函数,我称之为方法调用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象方法</title>
</head>
<body>

  <script>
    // 方法是依附在对象上的函数
    let person = {
      name: '小红',
      age: 18,
      // 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
      singing: function () {
        console.log('两只老虎,两只老虎,跑的快,跑的快...')
      },
      run: function () {
        console.log('我跑的非常快...')
      }
    }
    
    // 调用对象中 singing 方法
    person.singing()
    // 调用对象中的 run 方法
    person.run()

  </script>
</body>
</html>

扩展:也可以动态为对象添加方法,动态添加与直接定义是一样的,只是语法上更灵活。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript 基础 - 对象方法</title>
</head>
<body>

  <script>
    // 声明一个空的对象(没有任何属性,也没有任何方法)
	let user = {}
    // 动态追加属性
    user.name = '小明'
    user.['age'] = 18
    
    // 动态添加方法
    user.move = function () {
      console.log('移动一点距离...')
    }
    
  </script>
</body>
</html>

注:无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的。

null

null 也是 JavaScript 中数据类型的一种,通常只用它来表示不存在的对象。使用 typeof 检测类型它的类型时,结果为 object

遍历对象
1
2
3
4
5
6
7
8
let obj = {
    uname: 'pink'
}
for(let k in obj) {
    // k是属性名,并且是带引号的字符串类型
    //所以如果使用obj.k 就相当于写 obj.'uname' ,会调用失败
    //所以要用另一种调用方法:obj[k]
}

for in 不提倡遍历数组 因为 k 是 字符串

例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let obj = {
      name: '张三',
      age: 18,
      gender: '男'
    }
    for (let k in obj) {
      console.log(obj[k])
    }
    console.log('-------');
    for (let k in obj) {
      console.log(obj.k)
    }
  </script>
</body>
</html>

效果:

image-20241019170125259

遍历数组对象
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let students = [
        { name: '小明', age: 18, gender: '男', hometown: '河北省' },
        { name: '小红', age: 19, gender: '女', hometown: '河南省' },
        { name: '小刚', age: 17, gender: '男', hometown: '山西省' },
        { name: '小丽', age: 18, gender: '女', hometown: '山东省' }
    ]
    for (let i = 0; i < students.length; i++) {
      console.log(students[i])
      console.log(students[i].name)
    }
  </script>
</body>
</html>

image-20241019171123292

学生信息表案例练习

将学生信息数据渲染到页面中

效果图:

image-20241019172530230

代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        table {
            width: 600px;
            text-align: center;
        }

        table,
        th,
        td {
            border: 1px solid #ccc;
            border-collapse: collapse;
        }

        caption {
            font-size: 18px;
            margin-bottom: 10px;
            font-weight: 700;
        }

        tr {
            height: 40px;
            cursor: pointer;
        }

        table tr:nth-child(1) {
            background-color: #ddd;
        }

        table tr:not(:first-child):hover {
            background-color: #eee;
        }
    </style>
</head>
<body>
    <table>
        <caption>学生列表</caption>
        <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>性别</th>
            <th>家乡</th>
        </tr>
       
        <script>
            let students = [
                { name: '小明', age: 18, gender: '男', hometown: '河北省' },
                { name: '小红', age: 19, gender: '女', hometown: '河南省' },
                { name: '小刚', age: 17, gender: '男', hometown: '山西省' },
                { name: '小丽', age: 18, gender: '女', hometown: '山东省' }
            ]
            for (let i = 0; i < students.length; i++) {
                document.write(`
                <tr>
                    <td>${i + 1}</td>
                    <td>${students[i].name}</td>
                    <td>${students[i].age}</td>
                    <td>${students[i].gender}</td>
                    <td>${students[i].hometown}</td>
                </tr>
                `)
            }
        </script>
    </table>
</body>
</html>

内置对象

回想一下我们曾经使用过的 console.logconsole其实就是 JavaScript 中内置的对象,该对象中存在一个方法叫 log,然后调用 log 这个方法,即 console.log()

除了 console 对象外,JavaScritp 还有其它的内置的对象

Math

Math 是 JavaScript 中内置的对象,称为数学对象,这个对象下即包含了属性,也包含了许多的方法。

属性
  • Math.PI,获取圆周率
1
2
// 圆周率
console.log(Math.PI);
方法
  • Math.random,生成 0 到 1 间的随机数
1
2
// 0 ~ 1 之间的随机数, 包含 0 不包含 1
Math.random()
  • Math.ceil,数字向上取整
1
2
// 舍弃小数部分,整数部分加1
Math.ceil(3.4)
  • Math.floor,数字向下取整
1
2
// 舍弃小数部分,整数部分不变
Math.floor(4.68)
  • Math.round,四舍五入取整
1
2
3
4
5
// 取整,四舍五入原则
Math.round(5.46539)
Math.round(4.849)
Math.round(-1.5)//-1
Math.round(-1.51)//-2
  • Math.max,在一组数中找出最大的
1
2
// 找出最大值
Math.max(10, 21, 7, 24, 13)
  • Math.min,在一组数中找出最小的
1
2
// 找出最小值
Math.min(24, 18, 6, 19, 21)
  • Math.pow,幂方法
1
2
3
// 求某个数的多少次方
Math.pow(4, 2) // 求 4 的 2 次方
Math.pow(2, 3) // 求 2 的 3 次方
  • Math.sqrt,平方根
1
2
// 求某数的平方根
Math.sqrt(16)
  • Math.abs,绝对值
1
2
// 求某数的绝对值
Math.abs(-12.3)

数学对象提供了比较多的方法,这里不要求强记,通过演示数学对象的使用,加深对对象的理解。

详情见:Math - JavaScript | MDN (mozilla.org)

随机数函数练习

Math.random() 随机数函数, 返回一个0 - 1之间,并且包括0不包括1的随机小数 [0, 1)

  • 如何生成0-10的随机整数?(包括0和10)
1
2
// 取0-11的随机数后向下取整
Math.floor(Math.random() * 11)
  • 如何生成5-10的随机整数?(包括5和10)
1
Math.floor(Math.random() * 6) + 5
  • 如何生成N~M之间的随机整数?(包括N和M)
1
Math.floor(Math.random() * (M - N + 1)) + N
  • 从数组中随机选一个
1
2
3
let arr = ['red', 'green', 'blue']
let random = Math.floor(Math.random() * arr.length)
console.log(arr[random])
  • 猜数字游戏

需求:程序随机生成 1~10 之间的一个数字,用户输入一个数字

①:如果大于该数字,就提示,数字猜大了,继续猜

②:如果小于该数字,就提示,数字猜小了,继续猜

③:如果猜对了,就提示猜对了,程序结束

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    let random = Math.floor((Math.random() * 10) + 1)
    while (true) {
      let temp = +prompt('请输入一个1-10之间的数')
      if (temp > random) {
      alert('猜大了')
      }else if (temp < random){
        alert('猜小了')
      }else {
        alert('猜对了')
        break
      }
    }
  </script>
</body>
</html>

当猜的次数有限时,可以写一个开关变量来辅助

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <style>
  </style>
</head>
<body>
  <script>
    let random = Math.floor((Math.random() * 10) + 1)
    let flag = true   //生成一个开关变量
    for (let i = 1; i <= 3; i++) {
      let temp = +prompt('请输入一个1-10之间的数')
      if (temp > random) {
        alert('猜大了')
      }else if (temp < random){
        alert('猜小了')
      }else {
        flag = false  //猜对后改成false
        alert('猜对了')
        break
      }
    }
    // 3次都没猜对,flag就还是true
    if (flag) {
      alert('次数已用完')
    }
  </script>
</body>
</html>
  • 生成随机颜色

需求:该函数接收一个布尔类型参数,表示颜色的格式是十六进制还是rgb格式。

①:如果参数传递的是true或者无参数,则输出 一个随机十六进制的颜色

②:如果参数传递的是false,则输出 一个随机rgb的颜色

③:格式:

function getRandomColor(flag){ }

console.log(getRandomColor(true)) //#ffffff

console.log(getRandomColor(false)) //rgb(255,255,255)

分析:

提示: 16进制颜色格式为: ‘#ffffff’ 其中f可以是任意 0-f之间的字符,需要用到数组,

let arr = [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ’d’, ’e’, ‘f’]

提示: rgb颜色格式为: ‘rgb(255,255,255) ’ 其中255可以是任意0-255之间的数字

步骤:

①:如果参数为true或者无参数,则处理16进制颜色,核心思想是循环6次,生成随机的6个数字(取

值范围0~15),根据这个数字去找数组的值,然后和 # 拼接起来,并且返回值。

②:如果参数为false,随机生成一个0~255的数给三个变量,分别作为 r g b 三个颜色,之后拼接字

符串rgb(255,255,255)格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script>
    // 写一个生成N~M之间随机整数的函数,方便后续使用
    function getRandomInt(N, M) {
      return Math.floor(Math.random() * (M - N + 1)) + N
    }

    // 自定义一个随机颜色函数
    function getRandomColor(flag = true) {
      // 如果传入true或无实参传入,则返回格式为十六进制的颜色
      if(flag) {
        let temp = '#'
        let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
        for (let i = 1; i <= 6; i++) {
          // 每次从数组中抽一个出来
          let random = getRandomInt(0, arr.length - 1)
          // 把抽出来的接到temp中
          temp += arr[random]
        }
        return `${temp}`
      }
      // 如果传入false,则返回格式为rgb的颜色
      else {
        let r = getRandomInt(0, 255)
        let g = getRandomInt(0, 255)
        let b = getRandomInt(0, 255)
        return `rgb(${r}, ${g}, ${b})`
      }
    }

    // 调用函数getRandomColor()
    console.log(getRandomColor(true))
    console.log(getRandomColor(false))
    console.log(getRandomColor())
  </script>
</body>
</html>

拓展

基本数据类型和引用数据类型

简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型。

  • 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型

string ,number,boolean,undefined,null

  • 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型

通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的

栈;

简单数据类型存放到栈里面

2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

引用数据类型存放到堆里面

image-20241019221812916

简单类型的内存分配
  • 值类型(简单数据类型): string ,number,boolean,undefined,null

  • 值类型变量的数据直接存放在变量(栈空间)中

image-20241019222042620

复杂类型的内存分配
  • 引用类型(复杂数据类型):通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

  • 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

image-20241019222159635

小练习
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let num1 = 10
let num2 = num1
num2 = 20
console.log(num1)//(1)


let obj1 = {
  age: 18
}
let obj2 = obj1
obj2.age = 20
console.log(obj1.age)//(2)

答案:

(1) 10 ; (2) 20

(1)此时num为简单数据类型,直接存入栈中,把num1赋值给num2后,num2获得了一块新的栈空间,与num1的栈空间相互独立,互不影响

(2)此时obj为复杂数据类型,栈空间里存放的是地址,真正的对象实例存放在堆空间中,当把obj1赋值给obj2后,obj2获得了一块存放着地址的栈空间,虽然obj1和obj2的栈空间互不影响,但存放的地址是相同的,无论通过obj1还是obj2的地址,找到的对象实例都是同一个,所以对obj2的对象实例进行修改会影响到obj1

视频讲解:https://www.bilibili.com/video/BV1Y84y1L7Nn?t=817.3&p=77

综合案例

需求:根据数据渲染列表页面

效果图:

![](/assets/GIF 2024-10-19 22-02-18.gif)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>学车在线首页</title>
    <style>
      * {
          margin: 0;
          padding: 0;
      }
      .w {
          width: 1200px;
          margin: auto;
      }
      body {
          background-color: #f3f5f7;
      }
      li {
          list-style: none;
      }
      a {
          text-decoration: none;
      }
      .clearfix:before,.clearfix:after {
          content:"";
          display:table; 
        }
        .clearfix:after {
          clear:both;
        }
        .clearfix {
          zoom:1;
      }   
      

      .box {
          margin-top: 30px;
      }
      .box-hd {
          height: 45px;
      }
      .box-hd h3 {
          float: left;
          font-size: 20px;
          color: #494949;
      }
      .box-hd a {
          float: right;
          font-size: 12px;
          color: #a5a5a5;
          margin-top: 10px;
          margin-right: 30px;
      }
      /* 把li 的父亲ul 修改的足够宽一行能装开5个盒子就不会换行了 */
      .box-bd ul {
          width: 1225px;
      }
      .box-bd ul li {
          position: relative;
          top: 0;
          float: left;
          width: 228px;
          height: 270px;
          background-color: #fff;
          margin-right: 15px;
          margin-bottom: 15px;
          transition: all .3s;
      }
      .box-bd ul li a {
          display: block;
      }
      .box-bd ul li:hover {
          top: -8px;
          box-shadow: 0 15px 30px rgb(0 0 0 / 10%);
      }
      .box-bd ul li img {
          width: 100%;
      }
      .box-bd ul li h4 {
          margin: 20px 20px 20px 25px;
          font-size: 14px;
          color: #050505;
          font-weight: 400;
      }
      .box-bd .info {
          margin: 0 20px 0 25px;
          font-size: 12px;
          color: #999;
      }
      .box-bd .info span {
          color: #ff7c2d;
      }
    </style>
</head>
<body>
    <!-- 4. box核心内容区域开始 -->
    <div class="box w">
        <div class="box-hd">
            <h3>精品推荐</h3>
            <a href="#">查看全部</a>
        </div>
        <div class="box-bd">
            <ul class="clearfix">
                <script>
                  let data = [
                        {
                            src: 'images/course01.png',
                            title: 'Think PHP 5.0 博客系统实战项目演练',
                            num: 1125
                        },
                        {
                            src: 'images/course02.png',
                            title: 'Android 网络动态图片加载实战',
                            num: 357
                        },
                        {
                            src: 'images/course03.png',
                            title: 'Angular2 大前端商城实战项目演练',
                            num: 22250
                        },
                        {
                            src: 'images/course04.png',
                            title: 'Android APP 实战项目演练',
                            num: 389
                        },
                        {
                            src: 'images/course05.png',
                            title: 'UGUI 源码深度分析案例',
                            num: 124
                        },
                        {
                            src: 'images/course06.png',
                            title: 'Kami2首页界面切换效果实战演练',
                            num: 432
                        },
                        {
                            src: 'images/course07.png',
                            title: 'UNITY 从入门到精通实战案例',
                            num: 888
                        },
                        {
                            src: 'images/course08.png',
                            title: 'Cocos 深度学习你不会错过的实战',
                            num: 590
                        },
                    ]
                    for (let i = 0; i < data.length; i++){
                        document.write(`
                        <li>
                        <a href="#">
                            <img src="${data[i].src}" title="${data[i].title}">
                            <h4>
                                ${data[i].title}
                            </h4>
                            <div class="info">
                                <span>高级</span> • <span>${data[i].num}</span>人在学习
                            </div>
                        </a>
                        </li>
                        `)
                    }
                </script>
            </ul>
        </div>
    </div>
</body>
</html>
本站于2025年3月26日建立
使用 Hugo 构建
主题 StackJimmy 设计