JS基础学习笔记

day01-基础语法

1.输入输出语法

1
2
3
4
5
6
7
8
9
10
11
<script>
//输入
prompt('请输入您的姓名:')
//输出
alert()
document.write('hello')
document.write('<h1>hello</h1>')
console.log('hhh')
</script>


2.变量

1
2
3
//声名多个变量
let age=18,name='lisi'
console.log(age,name)

2.1变量名命名规则

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

  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>

2.2 let 和 var 的区别

var声明:

  • 可以先使用 再声明(不合理)
  • var声明的变量可重复声明(不合理)
  • 比如变量提升、全局变量、没有块级作用域等等

使用let即可

3.常量

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

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

命名规范:和变量一致

1
const PI = 3.14

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

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
<!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

//特殊NaN
console.log("15"-2) //显示NaN
console.log(NaN-2) //显示NaN
console.log(NaN+2) //显示NaN
console.log(NaN===NaN) //false
</script>
</body>
</html>

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

4.1字符串类型

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

注意事项:

  1. 无论单引号或是双引号必须成对使用
  2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已
  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="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
let age =18
document.write(`我的年龄${age}hhh`) //反引号包裹

4.2布尔类型

表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 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>
let isCool = true // 是的,摔死了!
isCool = false // 不,套马杆的汉子!

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

4.3undefined

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!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和undefine的区别

  • undefined表示没有赋值
  • null表示赋值了,但是内容为空

5.类型转换

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

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

5.1隐式转换

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

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' // 字符串
console,log(typeof +'123') //number
// 结果为 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 的特征,后续学习中还会遇到,目前先需要理解什么是隐式转换。

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

5.2显式转换

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

5.2.1Number

通过 Number 显示转换成数值类型,当转换失败时结果为 NaN(Not a 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
27
<!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)
ParseInt()
ParseFloat()
// 检测转换后的类型
// console.log(typeof t);
console.log(t + f) // 结果为 20

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

day02-运算符、控制语句

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

1.运算符

1.1算术运算符

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

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

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

注意:在计算失败时,显示的结果是 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赋值运算符

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

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

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

1.3自增/自减运算符

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

注意:

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

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

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

1.4比较运算符

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

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

1.5逻辑运算符

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

符号 名称 日常读法 特点 口诀
&& 逻辑与 并且 符号两边有一个假的结果为假 一假则假
\ \ 逻辑或 或者 符号两边有一个真的结果为真 一真则真
! 逻辑非 取反 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)
console.log(false && true)
console.log(3 < 5 && 3 > 2)
console.log(3 < 5 && 3 < 2)
console.log('-----------------')
// 逻辑或 一真则真
console.log(true || true)
console.log(false || true)
console.log(false || false)
console.log('-----------------')
// 逻辑非 取反
console.log(!true)
console.log(!false)

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

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

1.6运算符优先级

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

2.语句

2.1 分支语句

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

分支语句包含:

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

2.1.1 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>

2.1.2 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>

2.1.3 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>

2.1.4 三元运算符(三元表达式)

使用场景: 一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 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)

2.1.4 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>

2.1.5 断点调试

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

浏览器打开调试界面

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

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

2.2 循环语句

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

学习路径:

1.while循环

2.for 循环(重点)

2.2.1 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>

2.2.2 中止循环

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>

2.2.3 无限循环

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
}
}

day3-循环、数组

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

  1. 共同点

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

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

1.1 for 语句

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

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

1.1.1 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 一样,如果不合理设置增量和终止条件,便会产生死循环。
  1. 跳出和终止循环
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.1.2 循环嵌套

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

实际上 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>`)
}
}

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

1.1.2.1 倒三角

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>')
}

1.1.2.2 九九乘法表

样式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(`
<div> ${j} x ${i} = ${j * i} </div>
`)
}
document.write('<br>')
}

1.2 数组

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

1.2.1 数组是什么?

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

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

1.2.2 数组的基本使用

1.2.2.1 定义数组和数组单元

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

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

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

1.2.2.2 访问数组和数组索引

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

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

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.2.3 数据单元值类型

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

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>

1.2.2.4 数组长度属性

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

1
2
3
4
5
6
<script>
// 定义一个数组
let arr = ['html', 'css', 'javascript']
// 数组对应着一个 length 属性,它的含义是获取数组的长度
console.log(arr.length) // 3
</script>

1.2.3 操作数组

数组做为对象数据类型,不但有 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
<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)

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

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

day4-函数

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

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

1.1 函数

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

1.1.1 声明和调用

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

1.1.1.1 声明(定义)

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

function

1.1.1.2 调用

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

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.1.2 参数

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

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

  • 传入数据列表
  • 声明这个函数需要传入几个数据
  • 多个数据用逗号隔开
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. 调用函数传递的实参要与形参的顺序一致

1.2.1 形参和实参

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

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

形参可以理解为是在这个函数内声明的变量(比如 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.1.3 返回值

函数的本质是封装(包裹),函数体内的逻辑执行完毕后,函数外部如何获得函数内部的执行结果呢?要想获得函数内部逻辑的执行结果,需要通过 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>

总结:

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

1.1.4 作用域

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

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

1.1.4.1 全局作用域

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

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

1.1.4.2 局部作用域

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

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

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

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

1.1.5 匿名函数

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

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

1.1.5.1 函数表达式

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

1.1.5.2 立即执行函数

1
2
(function(){ xxx  })();
(function(){xxxx}());

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

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

​ 在能够访问到的情况下 先局部 局部没有在找全局

1.1.6 逻辑中断

1
2
3
4
function add(a,b){
num1 = a || 10
num2 = b || 20 //默认值
}

day6-对象

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

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

对象

对象是 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>

方法和调用

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

  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
let obj = {
uname: 'pink'
}
for(let k in obj) {
// k 属性名 字符串 带引号 obj.'uname' k === 'uname'
// obj[k] 属性值 obj['uname'] obj[k]
}

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

1) for in

主要用来遍历对象

1
2
3
4
5
let father = {name:'张三', age:18, study:function(){}};

for(const n in father) {
console.log(n);
}
  • 其中 const n 代表遍历出来的属性名
  • 注意1:方法名也能被遍历出来(它其实也算一种特殊属性)
  • 注意2:遍历子对象时,父对象的属性会跟着遍历出来
1
2
3
4
5
6
let son = Object.create(father);
son.sex = "男";

for(const n in son) {
console.log(n);
}
  • 注意3:在 for in 内获取属性值,要使用 [] 语法,而不能用 . 语法
1
2
3
for(const n in son) {
console.log(n, son[n]);
}

2) for of

主要用来遍历数组,也可以是其它可迭代对象,如 Map,Set 等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let a1 = [1,2,3];

for(const i of a1) {
console.log(i);
}

let a2 = [
{name:'张三', age:18},
{name:'李四', age:20},
{name:'王五', age:22}
];

for(const obj of a2) {
console.log(obj.name, obj.age);
}

for(const {name,age} of a2) {
console.log(name, age);
}

3) try catch

1
2
3
4
5
6
7
8
9
10
11
12
let stu1 = {name:'张三', age:18, address: {city:'北京'}};
let stu2 = {name:'张三', age:18};

function test(stu) {
try {
console.log(stu.address.city)
} catch(e) {
console.log('出现了异常', e.message)
} finally {
console.log('finally');
}
}

内置对象

回想一下我们曾经使用过的 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
// 取整,四舍五入原则
Math.round(5.46539)
Math.round(4.849)
  • 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)

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