Web前端必学的 JS 入门教程
1. JavaScript介绍
1.1 JavaScript 是什么
1. JavaScript (是什么?)
是一种运行在客户端(浏览器)的编程语言,实现人机交互效果
2. 作用(做什么?)
网页特效(监听用户的一些行为让网页作出对应的反馈)
表单验证(针对表单数据的合法性进行判断)
数据交互(获取后台的数据,渲染到前端)
服务端编程(node.js)
3. JavaScript的组成(有什么?)

ECMAScript:
规定了js基础语法核心知识。
比如:变量、分支语句、循环语句、对象等等
Web APIs:
DOM 操作文档,比如对页面的元素进行移动、大小、添加删除等操作
BOM 操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等
权威网站:MDN
1.2 JavaScript 书写位置
1. 内部 JavaScript
直接写在html文件里,用script标签包住
规范:script标签写在</body>上面
注意事项
我们将<script>放在HTML文件的底部附近的原因是浏览器会按照代码在文件中的顺序加载HTML
如果先加载的 JavaScript 期望修改其下方的 HTML,那么它可能由于 HTML 尚未被加载而失效
因此,将JavaScript 代码放在 HTML页面的底部附近通常是最好的策略
2. 外部 JavaScript
代码写在以 .js结尾的文件里
语法:通过script标签,引入到html页面中
注意事项
1. script标签中间无需写代码,否则会被忽略!
2. 外部JavaScript会使代码更加有序,更易于复用,且没有了脚本的混合,HTML也会更加易读,因此这是个好的习惯
3. 内联 JavaScript
代码写在标签内部
语法:
注意:此处作为了解即可,但是后面vue框架会用这种模式
1.3 JavaScript 的注释
1. 单行注释
- 符号://
- 快捷键:ctrl + /
2. 块注释
- 符号:/* */
- 快捷键:shift + alt + A
1.4 JavaScript的结束符
1. 结束符
- 代表语句结束
- 英文分号
- 可写可不写
- 换行符(回车)会被识别成结束符,所以一个完整的语句,不要手动换行
- 因此在实际开发中有许多人主张书写 JavaScript 代码时省略结束符
- 但为了风格统一,要写结束符就每句都写,要么每句都不写(按照团队要求)
1.5 输入和输出语法
1. 输出语法:
document.write('要输出的内容')
- 向body内输出内容
- 如果输出的内容写的是标签,也会被解析成网页元素
alert('要输出的内容')
- 页面弹出警告对话框
console.log('控制台打印')
- 控制台输出语法,程序员调试使用
2. 输入语法:
prompt('请输入您的姓名:')
- 显示一个对话框,对话框中包含一条文字信息,用来提示用户输入文字
1.6 字面量
在计算机科学中,字面量(literal)是在计算机中描述 事 / 物
比如:[] 数组字面量 {} 对象字面量 等等
2. 变量
2.1 变量是什么
变量不是数据本身,变量是计算机存储数据的容器。可以理解为是一个个用来装东西的纸箱子。
2.2 变量基本使用
1. 声明变量:
要想使用变量,首先需要创建变量
语法:
let 变量名
- 声明变量有两部分构成:声明关键字、变量名(标识)
- let 即关键字(let:允许、许可、让、要),所谓关键字是系统提供的专门用来声明(定义)变量的词语
例 let age
age为变量名,也叫标识符
2. 变量赋值:
定义了一个变量后,你就能够初始化它(赋值)。在变量名之后跟上一个“=”,然后是数值。
注意:是通过变量名来获取变量里面的数据
3. 更新变量:
变量赋值后,还可以通过简单地给它一个不同的值来更新它

注意:let不允许多次声明一个变量
4. 声明多个变量
变量赋值后,还可以通过简单地给它一个不同的值来更新它
let age = 19, uname = 'ww'
/* 用户输入内容,浏览器输出程序
第一步:输入:用户输入框:prompt()
第二步:内部处理:保存数据
第三步:输出:页面打印document.write() */
<script>
let name = prompt('请输入:')
document.write(name)
</script>
/* 交换变量的值
步骤:
1.声明一个临时变量temp
2.把num1的值赋值给temp
3.把num2的值赋值给num1
4.把temp的值给num2 */
<script>
let num1 = 10
let num2 = 20
let temp
temp = num1
num1 = num2
num2 = temp
console.log(num1, num2)
</script>
2.3 变量的本质
内存:计算机中存储数据的地方,相当于一个空间
变量:是程序在内存中申请的一块用来存放数据的小空间
2.4 变量命名规则与规范
规则:必须遵守,不遵守报错
规范:建议,不遵守不会报错,但不符合业内通识
1. 规则:
- 不能用关键字
- 关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:let、var、if、for等
- 只能用下划线、字母、数字、$组成,且数字不能开头
- 字母严格区分大小写,如Age和age是不同的变量
2. 规范:
- 起名要有意义
- 遵守小驼峰命名法
- 第一个单词首字母小写,后面每个单词首字母大写。
拓展-let和var的区别
let为了解决var的一些问题
var声明:
- 可以先使用在声明(不合理)
- var声明过的变量可以重复声明(不合理)
- 比如变量提升、全局变量、没有块级作用域等等
变量拓展-数组
- 数组(Array)是一种可以按顺序保存多个数据
1.1 数组的基本使用
1. 声明语法
let 数组名 = [数据1, 数据2, ..., 数据n]
- 数组是按顺序保存,所以每个数据都有自己的编号
- 在数组中,数据的编号也叫索引或下标
2. 一些术语:
- 元素:数组中保存的每个数据都叫数组元素
- 下标:数组中数据的编号
- 长度:数组中数据的个数,通过数组的length属性获得
3. 数据类型
3.1 数据类型
计算机世界中的万事万物都是数据
计算机程序可以处理大量的数据,为什么要给数据分类
- 更加充分和高效的利用内存
- 也更加方便程序员使用数据
JS数据类型整体分为两大类
- 基本数据类型
- number 数字型
- string 字符串型
- boolean 布尔型
- undefined 未定义型
- null 空类型
- 引用数据类型
- object 对象
- function 函数
- array 数组
3.2 数据类型 - 数字类型(number)
即我们数学中学习到的数字,可以是整数、小数、正数、负数。
JavaScript中的正数、负数、小数等 统一称为 数字类型
注意事项
- JS是弱数据类型,变量到底属于哪种类型,只有赋值之后,我们才能确认
- Java是强数据类型 例如 int a = 3 必须是整数
3.2 数据类型 - 字符串类型(string)
通过单引号('')、双引号("")或反引号(`)包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号
注意事项:
- 无论单引号或是双引号必须成对使用
- 单引号/双引号可以互相嵌套,但是不以自己嵌套自己(口诀:外双内单,或者外单内双)
- 必要时可以使用转义符 \,输出单引号或双引号
字符串拼接:+
模板字符串
1. 作用
- 拼接字符串和变量
- 在没有它之前,要拼接变量比较麻烦
document.write('大家好,我叫' + name + ',今年' + age + '岁')
2. 符号
- ``
- 在英文输入模式下按键盘的tab上方那个键(1左边那个键)
- 内容拼接变量时,用${}包住变量
- 用反引号包含的内容可以换行
document.write(`大家好,我叫${name},今年${age}岁`)
// 页面输出用户信息案例 <script> let uname = prompt('请输入您的姓名:') let age = prompt('请输入您的年龄:') document.write(`您是${uname},今年${age}岁啦`) </script>
3.3 数据类型 - 布尔类型(boolean)
表示肯定或否定时在计算机中对应的是布尔类型数据
它有两个固定的值 true和false,表示肯定的数据用true(真),表示否定的数据用false(假)
3.4 数据类型 - 未定义类型(undefined)
未定义是比较特殊的类型,只有一个值 undefined
什么情况出现未定义类型?
只声明变量不赋值,变量的默认值为undefined,一般很少【直接】为某个变量赋值为undefined
| 情况 | 说明 | 结果 |
|---|---|---|
| let age; console.log(age) | 只声明 不赋值 | undefined |
| console.log(age) | 不声明 不赋值 直接使用 | 报错 |
| age = 10; console.log(age) | 不声明 只赋值 | 10(不提倡) |
工作中的使用场景
我们开发中经常声明一个变量,等待传送过来的数据。
如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是undefined,就判断用户是否有数据传递过来
3.5 数据类型 - 空类型(null)
null表示值为空
let obj = null
null和undefined区别:
- undefined表示没有赋值
- null表示赋值了,但是内容为空
null开发中的使用场景:
官方解释:把null作为尚未创建的对象
大白话:将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个null
3.6 控制台输出语句和检测数据类型
1. 控制台输出语句
- 控制台语句经常用于测试结果来使用
- 可以看出数字型和布尔型颜色为蓝色,字符串和undefined颜色为灰色
2. 通过typeof关键字检测数据类型
let age = 18
let unage = '白羊'
let flag = false
let buy
console.log(typeof age) // number
console.log(typeof uname) // string
console.log(typeof flag) // boolean
console.log(typeof buy) // undefined
4. 类型转换
4.1 为什么要类型转换
JavaScript是弱数据类型:JavaScript也不知道变量到底属于哪种数据类型,只有赋值了才清楚
坑:使用表单、prompt获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算
此时需要转换变量的数据类型
通俗来说,把一种数据类型的变量转换成我们需要的数据类型
4.2 隐式转换
某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换为隐式转换
规则:
- +号两边只要有一个是字符串,都会把另外一个转成字符串
- 除了+以外的算术运算符 比如- * / 等都会把数据转成数字类型
缺点:
- 转换类型不明确,靠经验才能总结
小技巧:
- +号作为正号解析可以转换成Number
4.3 显式转换
编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换
概念:
自己写代码告诉系统该转成什么类型
转换为数字型
- Number(数据)
- 转成数字类型
- 如果字符串内容里有非数字,转换失败时结果为NaN (Not a Number)即不是一个数字
- NaN也是number类型的数据,代表非数字
- parseInt(数据)
- 只保留整数
- parseFloat(数据)
- 可以保留小数
- parseInt和parseFloat常用作过滤单位:parseInt(100px)
转换为字符型:
- String(数据)
- 变量.toString(进制)
console.log(String(10))
let age = 10
console.log(age.toString())
// 将10转为二进制
console.log(age.toString(2))
用户订单信息案例
<style>
* {
margin: 0;
padding: 0;
}
table {
margin: 0 auto;
text-align: center;
border-collapse: collapse;
}
table th,
td {
border: 1px solid #000;
padding: 15px;
}
table caption {
margin: 15px 0;
}
</style>
<body>
<script>
// 需要输入3个数据,所以需要3个变量来存储 price num address
let price = prompt('请输入商品价格:')
let num = prompt('请输入商品数量:')
let address = prompt('请输入收货地址:')
// 需要计算总的价格total
// *为隐式转换,把字符串转成数字类型
let total = price * num
// 页面打印生成表格,里面填充数据即可
// 记得最好使用模板字符串
document.write(`
<table>
<tbody>
<caption>用户订单信息案例</caption>
<tr>
<th>商品名称</th>
<th>商品价格</th>
<th>商品数量</th>
<th>总价</th>
<th>收货地址</th>
</tr>
<tr>
<td>小米手机青春PLUS</td>
<td>${price}元</td>
<td>${num}</td>
<td>${total}元</td>
<td>${address}</td>
</tr>
</tbody>
</table>
`)
</script>
</body>
5. 运算符
5.1 算术运算符
数学运算符也叫算术运算符,主要包括加、减、乘、除、取余(求模)
- +:求和
- -:求差
- *:求积
- /:求商
- %:取模(取余数)
- 开发中经常作为某个数字能否被整除
同时使用多个运算符编写程序时,会按着某种顺序先后执行,我们称为优先级。
JavaScript中 优先级越高越先被执行,优先级相同时从左向右执行
- 乘、除、取余优先级相同
- 加、减优先级相同
- 乘、除、取余优先级大于加、减
- 使用()可以提升优先级
- 总结:先乘除后加减,有括号先算括号里面的~~~
计算圆的面积案例
<script>
// 计算圆的面积方法一
let r = prompt('请输入圆的半径:')
let result = 3.14 * r * r
document.write(`计算之后圆的面积是:${result}`)
// 计算圆的面积方法二
let r = prompt('请输入圆的半径:')
document.write(`计算之后圆的面积是${3.14 * r * r}`)
</script>
5.2 赋值运算符
赋值运算符:对变量进行赋值的运算符
- 已经学过的赋值运算符:= 将等号右边的值赋予给左边,要求左边必须是一个容器
- 其他赋值运算符:
- +=
-
<script> let num = 18 num += 1 // 也就是 num = num + 1 console.log(num); </script>
-
- -=
- *=
- /=
- %=
- +=
5.3 一元运算符
众多的JavaScript的运算符可以根据所需表达式的个数,分为一元运算符、二元运算符、三元运算符
- 二元运算符:
let num = 10 +20
- 一元运算符:
- 正负号
以前自加1
let num = 10
num = num + 1 // num+=1
更简便的写法
- 自增:
- 符号:++
- 作用:让变量的值+1
- 自减:
- 符号:--
- 作用:让变量的值-1
- 使用场景:
- 经常用于计数来使用。比如进行10次操作,用它来计算进行了多少次了
前置自增
- 每执行1次,当前变量数值+1
- 作用相当于num += 1

前置自增和后置自增单独使用没有区别

but:
- 前置自增和后置自增独立使用时二者并没有差别!
- 一般开发中我们都是独立使用
- 后面i++后置自增会使用相对较多
面试题

5.4 比较运算符
1. 比较运算符的介绍
作用:比较两个数据大小,是否相等
2. 比较运算符的使用
>、<、>=、<=、==:左右两边是否相等、!=:不相等、===:左右两边是否类型和值都相等、!==:左右两边是否不全等
比较结果为boolean类型,即只会得到true或false
3. 比较运算符的细节
字符串比较,是比较的字符对应的ASCII码
- 从左往右依次比较
- 如果第一位一样再比较第二位,以此类推
- 比较的少,了解即可
NaN不等于任何值,包括它本身
尽量不要比较小数,因为小数有精度问题
不同类型之间比较会发生隐式转换
5.5 逻辑运算符
1. 逻辑运算符的使用
| 符号 | 名称 |
| && | 逻辑与 |
| || | 逻辑或 |
| ! | 逻辑非 |
2.逻辑运算符里的短路
短路:只存在于&&和||中,当满足一定条件会让右边代码不执行
| 符号 | 短路条件 |
| && | 左边为false就短路 |
| || | 左边为true就短路 |
原因:通过左边能得到整个式子的结果,因此没必要再判断右边
运算结果:无论&&还||,运算结果都是最后被执行的表达式值,一般用在变量赋值
console.log(false && 20) // false
console.log(5 < 3 && 20) // false
console.log(undefined && 20) // undefined
console.log(null && 20) // null
console.log(0 && 20) // 0
console.log(10 && 20) // 20 不短路以 后面的为准
// 有5个值是当 false 来看的:fasle、 数字0、 ''、 undefined、 null、NaN
console.log(false || 20) // 20
console.log(5<3 || 20) // 20
console.log(undefined || 20) // 20
console.log(null || 20) // 20
console.log(0 || 20) // 20
console.log(10 || 20) // 10
// 判断一个数是4的倍数,且不是100的倍数
<script>
let num = prompt('请输入:')
console.log(num % 4 === 0 && num % 100 !== 0)
</script>
let num = prompt('请输入:')
num = num || 0 // 如果用户不输入,则返回0
console.log(num)
5.6 运算符优先级
| 优先级 | 运算符 | 顺序 |
| 1 | 小括号 | () |
| 2 | 一元运算符 | ++ -- ! |
| 3 | 算数运算符 | 先 * / % 后 + - |
| 4 | 关系运算符 | > >= < <= |
| 5 | 相等运算符 | == != === !== |
| 6 | 逻辑运算符 | 先 && 后 || |
| 7 | 赋值运算符 | = |
| 8 | 逗号运算符 | , |
- 一元运算符里面的逻辑非优先级很高
- 逻辑与比逻辑或优先级高
6. 语句
6.1 表达式和语句
- 表达式是一组代码的集合,JavaScript解释器会将其计算出一个结果
x = 7
3 + 4
num++
语句:
- js 整句或命令,js 语句是以分号结束(可以省略)
- 比如:if语句 for循环语句
区别:
- 表达式计算出一个值,但语句用来自行以使某件事发生(做什么事)
- 表达式 3+4
- 语句 alert() 弹出对话框
- 其实某些情况,也可以把表达式理解为语句,因为它是在计算结果,也是做事
6.2 分支语句
1. 程序三大流程控制语句
- 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
- 有的时候要根据条件选择执行代码,这种就叫分支结构
- 某段代码被重复执行,就叫循环结构
分支语句可以让我们有选择性的执行想要的代码
分支语句包含:
- lf分支语句
- 三元运算符
- switch语句
2. if 语句
if语句有三种使用:单分支、双分支、多分支
单分支使用语法:
if (条件) {
满足条件要执行的代码
}
- 括号内的条件为true时,进入大括号里执行代码
- 小括号内的结果若不是布尔类型时,会发生隐式转换转为布尔类型
双分支if语法:
if (条件) {
满足条件要执行的代码
} else {
不满足条件执行的代码
}
// 用户输入,如果工龄大于等于3年,年底奖金+2000,否则年底没奖金 <script> let age = prompt('请输入工龄:') let money = 20000 if (age >= 3){ `您的工资为${money + 2000}` } else { `您的工资为${money}` } </script>
让用户输入年份,判断这一年是闰年还是平年并输出 // 能被4整除但不能被100整除,或者被400整除的年份是闰年,否则都是平年 <script> // 因为prompt获取的是字符串,需要转为数字类型 let year = +prompt('请输入年份:') if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) { alert(`${year}是闰年`) } else { alert(`${year}是平年`) } </script>
多分支if语法:
if (条件1) {
代码1
} else if (条件2) {
代码2
} else if (条件3) {
代码3
} else {
代码n
}
释义:
- 先判断条件1,若满足条件1就执行代码1,其他不执行
- 若不满足则向下判断条件2,满足条件2执行代码2,其他不执行
- 若依然不满足继续往下判断,依次类推
- 若以上条件都不满足,执行else里的代码n
- 注:可以写N个条件,但这里演示只写2个
多分支if课堂案例:根据输入不同时间,输出不同的问候语注:
// 12点以前,输出上午好;18点以前,输出下午好;20点以前,输出晚上好
<script>
let time = prompt('请输入现在的小时数:')
if (time < 12) {
prompt(`上午好,好好学习`)
} else if (time < 18) {
prompt(`下午好,好好学习`)
} else if (time < 20) {
prompt(`晚上好,好好学习`)
} else {
prompt(`夜深了,好好睡觉`)
}
</script>
2. 三元运算符
- 其实是比if 双分支更简单的写法,有时候也叫做三元表达式
- 符号:?与∶配合使用
语法:
条件 ? 满足条件执行的代码 : 不满足条件执行的代码
- 一般用来取值
<script>
// 例:
console.log(true ? 1 : 2) // 1
console.log(false ? 1 : 2) // 2
</script>
// 判断两个数的大小
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
let result = num1 > num2 ? num1 : num2
document.write(`${result}大`)
<script>
// 数字补0案例
// 需要:用户输入1个数,如果数字小于10,则前面进行补0,比如09 03等
// 分析:1.为后期页面显示时间做铺垫 2.利用三元运算符补0计算
let num = prompt('请输入:')
let time = num >= 10 ? num : 0 + num
// let time = num < 10 ? num : 0 + num
document.write(time)
</script>
3. switch语句
switch (数据) {
case 值1:
代码1
break
case 值2:
代码2
break
default:
代码n
break
}
释义:
找到跟小括号里数据全等的case值,并执行里面对应的代码
数据和值若没有全等 === 的则执行default里的代码
1. switch case语句一般用于等值判断,不适合于区间判断
2. switch case一般需要配合break关键字使用,没有break会造成case穿透
switch (1) {
case 1:
alert(1)
break
case 2:
alert(2)
break
case 3:
alert(3)
break
default:
alert('没有数据')
}
简单计算器
/* 简单计算器
需求: 用户输入2个数字, 然后输入 + - * / 任何一个,可以计算结果
分析:
1. 用户输入数字
2. 用户输入不同算术运算符, 可以去执行不同的运算(switch) */
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
let fuhao = prompt('请输入运算符号:')
switch (fuhao) {
case '+':
alert(`${num1} + ${num2} = ${num1 + num2}`)
break
case '-':
alert(`${num1} - ${num2} = ${num1 - num2}`)
break
case '*':
alert(`${num1} * ${num2} = ${num1 * num2}`)
break
case '/':
alert(`${num1} / ${num2} = ${num1 / num2}`)
break
default:
alert('请输入+ - * /这些运算符号!')
}
6.3 循环语句
1. 断点调试
- 作用:学习时可以帮助更好的理解代码运行,工作时可以更快找到bug
- 浏览器打开调试界面
- 1. 按F12打开开发者工具
- 2. 点到sources一栏
- 3. 选择代码文件
- 4. 想在哪一行打断点,点击它的行号即可
- 5. 刷新
2. while循环
1. 循环:重复执行某段代码,而while:在...期间
while (循环条件) {
要重复执行的代码(循环体)
}
释义:
- 跟if语句很像,都要满足小括号里的条件为true才会进入执行代码
- while大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出
2. while循环注意事项:
循环的本质就是以某个变量为起始值,然后不断产生变化量,慢慢靠近终止条件的过程。所以,循环需要具备三要素:
- 1. 变量起始值
- 2. 终止条件(没有终止条件,循环会一直执行,造成死循环)
- 3. 变量变化量(用自增或者自减)
// 循环三要素
// 1. 变量起始值
let i = 1
// 2. 终止条件
while (i <= 10) {
document.write(`月薪过万 <br>`)
// 变量变化
i++
}
// 页面输出1~10
// 起始值
let i = 1
// 终止条件
while (i <= 10) {
document.write(`${i} <br>`)
// 变量变化
i++
}
// 输出1~100的累加和
// 起始值
let i = 1
let sum = 0
// 终止条件
while (i <= 100) {
sum = sum + i
// 变量变化
i++
}
document.write(`1~100的累加和是${sum}`)
// 计算1~100之间的所有偶数和
let i = 1
// 声明累加和的变量 sum
let sum = 0
while (i <= 100) {
// 首先利用if语句把i里面的是偶数筛选出来
if (i % 2 === 0) {
// 把筛选的i加到sum里面
sum = sum + i
}
i++
}
document.write(`1~100之间所有偶数和:${sum}`)
// 页面弹框案例
let love = ''
// 当条件为true时,才会向下执行
while (love !== '爱') {
love = prompt('Do you love me?')
}
简易取款机
// 循环的时候,需要反复提示输入框,所以提示框写到循环里面
let str = ''
// 提前准备一个金额预先存储一个数额
let money = 100
// 退出的条件是用户输入4(用户只要不输4就不退出)
while (str !== '4') {
str = prompt(`
请选择您的操作:
1. 取款
2. 存款
3. 查看余额
4. 退出
`)
// 输入不同的值,可以使用switch来执行不同的操作
switch (str) {
case '1':
let qu = +prompt('请输入取款金额:')
money = money - qu
break
case '2':
let cun = +prompt('请输入存款金额:')
money = money + cun
break
case '3':
alert(`您还有${money}元`)
break
}
}
分别输入四季度的数据得到柱形图
<style>
* {
margin: 0;
padding: 0;
}
.box {
display: flex;
width: 700px;
height: 300px;
border-left: 1px solid pink;
border-bottom: 1px solid pink;
margin: 50px auto;
justify-content: space-around;
align-items: flex-end;
text-align: center;
}
.box>div {
display: flex;
width: 50px;
background-color: pink;
flex-direction: column;
justify-content: space-between;
}
.box div span {
margin-top: -20px;
}
.box div h4 {
margin-bottom: -35px;
width: 70px;
margin-left: -10px;
}
</style>
<body>
<script>
let arr = []
for (let i = 1; i <= 4; i++) {
arr.push(+prompt(`请输入第${i}季度的数据`))
}
document.write(`<div class= "box">`)
for (let i = 0; i < arr.length; i++) {
document.write(`<div style= "height: ${arr[i]}px">
<span>${arr[i]}</span>
<h4>第${i+1}季度</h4>
</div>`)
}
document.write(`</div>`)
</script>
</body>
7 循环 - for
7.1 for循环基本使用
1. for循环语法
也是重复执行代码
好处:把声明起始值、循环条件、变化值写到一起,让人一目了然
for (声明记录循环次数的变量(相当于起始条件); 循环条件; 变化值(相当于变化量)) {
循环体
}
// 页面输出十句“月薪过万”
for (let i = 1; i <= 10; i++) {
document.write(`月薪过万 <br>`)
}
// 利用for循环输出1~100岁
for (let i = 1; i <= 100; i++) {
document.write(`我今年${i}岁了 <br>`)
}
// 求1~100之间所有的偶数和
let sum = 0
for (let i = 1; i <= 100; i++) {
if (i % 2 === 0) {
sum = sum + i
}
}
document.write(`1~100之间所有的偶数和:${sum}`)
// 页面中打印5个心形
for (let i = 1; i <= 5; i++) {
document.write('❤️🔥')
}
2. 遍历数组
// 页面中打印['马超', '赵云', '张飞', '关羽', '黄忠']
let arr = ['马超', '赵云', '张飞', '关羽', '黄忠']
/*
document.write(arr[0])
document.write(arr[1])
document.write(arr[2])
document.write(arr[3])
document.write(arr[4])
*/
for (let i = 0; i < arr.length; i++){
// for (let i = 0; i <= 4; i++) {
document.write(`${arr[i]} <br>`)
}
7.2 退出循环
1. for循环和while循环有什么区别
- 当明确了循环的次数的时候推荐使用for循环
- 当不明确循环的次数的时候推荐使用while循环
2. 循环结束
- continue:结束本次循环,断续下次循环
- break:跳出所在的循环
for (let i = 1; i < 6; i++) {
if (i === 4) {
// continue // 1235
break // 123
}
document.write(i)
}
7.3 循环嵌套
for 循环嵌套
for (外部声明记录循环次数的变量; 循环条件; 变化值) {
for (内部声明记录循环次数的变量; 循环条件; 变化值) {
循环体
}
}
一个循环里再套一个循环,一般用在for循环里
for (let i = 1; i < 6; i++) {
for (let j = 1; j < 6; j++) {
document.write('❤️🔥') // 在一行中输出25个心心
}
}
记忆单词案例
for (let i = 1; i < 4; i++) { document.write(`第${i}天 <br>`) for (let j = 1; j < 6; j++) { document.write(`第${j}个单词 <br>`) } } // 运行结果如下
// 打印五行五列💖
// 外层循环控制打印行
for (let i = 1; i < 6; i++) {
// 里层循环控制每行打印几个(列)
for (let j = 1; j < 6; j++) {
document.write('💖')
}
// 五个心打印完了换行
document.write('<br>')
}
// 用户输入需要,打印对应的💖
let row1 = prompt('请输入行数:')
let row2 = prompt('请输入列数')
for (let i = 1; i <= row1; i++) {
// 里层循环控制每行打印几个(列)
for (let j = 1; j <= row2; j++) {
document.write('💖')
}
// 五个心打印完了换行
document.write('<br>')
}
// 打印直角三角形💖
/*
1. 利用双重for循环
2. 外层循环控制打印行,内层循环控制每行打印几个(列)
3. 内层循环的个数跟第几行是一一对应的
*/
for (let i = 1; i < 6; i++) {
for (let j = 1; j <= i; j++) {
document.write('💖')
}
document.write('<br>')
}
![]()
<style>
div {
display: inline-block;
line-height: 25px;
margin: 5px;
background-color: pink;
padding: 0 10px;
border: 1px solid hotpink;
color: deeppink;
border-radius: 5px;
box-shadow: 2px 2px 2px rgba(0, 0, 0, .2);
text-align: center;
}
</style>
<script>
// 打印九九乘法表
for (let i = 1; i < 10; i++) {
for (let j = 1; j <= i; j++) {
document.write(`
<div>${j} X ${i} = ${i * j}</div>
`)
}
document.write('<br>')
}
</script>
![]()
8. 数组
8.1 数组是什么
- 数组(Array)是一种可以按顺序保存数据的数据类型
- 为什么要数组?
- 思考:如果我想保存一个班里5个人的姓名怎么办?
- 如果有多个数据可以用数组保存起来
8.2 数组的基本使用
1. 声明语法
let 数组名 = [数据1, 数据2, ..., 数据n]
- 数组是按顺序保存,所以每个数据都有自己的编号
- 计算机中的编号从0开始
- 在数组中,数据的编号也叫索引或下标
- 数组可以存储任意类型的数据
2. 取值语法
数组名[下标]
通过下标取数据
3. 一些术语
- 元素:数组中保存的每个数据都叫数组元素
- 下标:数组中数据的编号
- 长度:数组中数据的个数,通过数组的length属性获得
let names = ['小明', '小刚', '小红', '小丽', '小米']
console.log(names[0]) // 小明
console.log(names[1]) // 小刚
console.log(names.length) // 5
4. 遍历数组
- 用循环把数组中每个元素都访问到,一般会用for循环遍历
for (let i = 0; i < 数组名.length; i++) {
数组名[i]
}
let nums = [10, 20, 30, 40, 50]
for (let i = 0; i < nums.length; i++) {
document.write(nums[i])
}
// 求数组[2, 6, 1, 7, 4]里面所有元素的和以及平均值
let arr = [2, 6, 1, 7, 4]
// 声明求和变量sum
let sum = 0
// 声明平均值
let average = 0
// 遍历数组,把里面每个数组元素加到sum里面
// 因 数组下标从0开始,所以i = 0
for (let i = 0; i < arr.length; i++) {
sum = sum + arr[i]
}
// 用求和变量sum除以数组的长度就可以得到数组的平均值
average = sum / arr.length
document.write(`这个同学的总分是:${sum},平均分是:${average}`)
// 求数组[2, 6, 1, 77, 52, 25, 7]中的最大值
let arr = [2, 6, 1, 77, 52, 25, 7]
// 声明一个保存最大元素的变量max
let max = 0
// 默认最大值可以取数组中的第一个元素
max = arr[0]
// 遍历这个数组,把里面每个数组元素和max相比较
for (let i = 1; i < arr.length; i++) {
// 如果这个数组元素大于max,就把这个数组存到max里面,否则继续下一轮比较
if (max < arr[i]) {
max = arr[i]
}
}
// 最后输出max
document.write(`这个数组中的最大值是:${max}`)
5. 操作数组
数组本质是数据集合,操作数据无非就是 增 删 改 查 语法:

1. 数组增加新的数据
数组.push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度(重点)
语法:
arr.push(元素1, ..., 元素n)
// 例:
let arr = ['hot', 'green']
document.write(arr.push('blue', 'yellow')) // 4
document.write(arr) // hot,green,blue,yellow
arr.unshift(新增的内容)方法将一个或多个元素添加到数组的开头,并返回该数组的新长度,用法同push
语法:
arr.unshift(元素1, ..., 元素n)
数组筛选:将[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中大于等于10的元素选出来,放入新数组
/*
1. 声明一个新的数组用于存放新数据newArr
2. 遍历原来的旧数组,找出大于等于10的元素
3. 依次追加给新数组newArr
*/
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)
// 数组筛选:将[2, 0, 6, 1, 77, 0, 52, 0, 25, 7]中不等于0的元素选出来,放入新数组
/*
1. 声明一个新的数组用于存放新数据newArr
2. 遍历原来的旧数组,找出不等于0的元素
3. 依次追加给新数组newArr
*/
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] !== 0) {
newArr.push(arr[i])
}
}
document.write(newArr)
2. 数组删除元素
数组.pop()方法从数组中删除最后一个元素,并返回该元素的值
语法:
arr.pop()
数组.shift()方法从数组中删除第一个元素,并返回该元素的值
语法:
arr.shift()
数组.splice()方法 删除指定元素
语法:
arr.splice(start, deleteCount)
// arr.splice(起始位置, 删除几个元素)
- start 起始位置
- 指定修改的开始位置(从0计数)
- deleteCount:
- 表示要移除的数组元素的个数
- 可选的。如果省略则默认从指定的起始位置删除到最后
删除元素的使用场景:
- 随机抽奖,中奖的用户就需要从数组里面删除,不允许重复抽奖
- 点击删除按钮,相关的数据会从商品数据中删除
9. 冒泡排序
冒泡排序是一种简单的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
比如数组[2,3,1,4,5]经过排序成为了[1,2,3,4,5]或者[5,4,3,2,1]

// 冒泡排序
let arr = [2, 6, 4, 3, 5, 1]
// 外层循环控制趟数,循环4次,arr.length - 1
for (let i = 0; i < arr.length - 1; i++) {
// 里层循环控制一趟交换几次,arr.length - i - 1
for (let j = 0; j < arr.length - i - 1; j++) {
// 交换两个变量
if (arr[j] > arr[j + 1]) {
let temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
document.write(arr)
// 根据用户输入的数据生成柱形图
// 第一步 构建基本结构 <style> * { margin: 0; padding: 0; } .box { display: flex; width: 700px; height: 300px; border-left: 1px solid pink; border-bottom: 1px solid pink; margin: 50px auto; justify-content: space-around; align-items: flex-end; text-align: center; } .box div { display: flex; width: 50px; background-color: pink; flex-direction: column; justify-content: space-between; } .box div span { margin-top: -20px; } .box div h4 { margin-bottom: -35px; width: 70px; margin-left: -10px; } </style>
<body>
<div class="box">
<div style="height: 123px;">
<span>123</span>
<h4>第一季度</h4>
</div>
<div style="height: 156px;">
<span>156</span>
<h4>第二季度</h4>
</div>
<div style="height: 120px;">
<span>120</span>
<h4>第三季度</h4>
</div>
<div style="height: 210px;">
<span>210</span>
<h4>第四季度</h4>
</div>
</div>
</body>
// 第二步 添加js内容
<script>
// 需要循环4次,所以可以把4个数据放到一个数组里面
let arr = []
for (let i = 0; i < arr.length; i++) {
// 利用循环,弹出4次框,同时存到数组里面
arr.push(prompt(`请输入第${i}季度的数据:`))
}
console.log(arr)
</script>
1 // 第三步
2 // 1. 注释body里面的内容,包括js内容
3 // 2. 加js内容,用js为页面添加盒子
4 document.write(`<div class="box">`)
5 document.write(`</div>`)
6
7 // 3. 有四季度,可以使用for循环,在上面第4行和第5行中间添加
8 for (let i = 1; i <= 4; i++){}
9
10 // 4. 在里面任意添加一季度的内容
11 <div style="height: 123px;">
12 <span>123</span>
13 <h4>第一季度</h4>
14 </div>
15
16 // 5. 取消前面注释的js内容
17
18 // 最终展示效果如下:
19 <script>
20 // 需要循环4次,所以可以把4个数据放到一个数组里面
21 let arr = []
22 for (let i = 0; i < arr.length; i++) {
23 // 利用循环,弹出4次框,同时存到数组里面
24 arr.push(prompt(`请输入第${i}季度的数据:`))
25 }
26 // console.log(arr)
27 document.write(`<div class="box">`)
28 for (let i = 0; i < arr.length; i++) {
29 document.write(`
30 <div style="height: 123px;">
31 <span>123</span>
32 <h4>第一季度</h4>
33 </div>
34 `)
35 }
36 document.write(`</div>`)
37 </script>
// 第四步 更改内容(第三步中的第30、31、32行)
<div style="height: ${arr[i]}px;">
<span>${arr[i]}</span>
<h4>第${i + 1}季度</h4>
</div>
// 根据用户输入的数据生成柱形图 // 总体效果如下: // CSS部分效果不变 <style> * { margin: 0; padding: 0; } .box { display: flex; width: 700px; height: 300px; border-left: 1px solid pink; border-bottom: 1px solid pink; margin: 50px auto; justify-content: space-around; align-items: flex-end; text-align: center; } .box div { display: flex; width: 50px; background-color: pink; flex-direction: column; justify-content: space-between; } .box div span { margin-top: -20px; } .box div h4 { margin-bottom: -35px; width: 70px; margin-left: -10px; } </style>
<script>
// 需要循环4次,所以可以把4个数据放到一个数组里面
let arr = []
for (let i = 1; i <= 4; i++) {
// 利用循环,弹出4次框,同时存到数组里面
arr.push(prompt(`请输入第${i}季度的数据:`))
}
// console.log(arr)
document.write(`<div class="box">`)
for (let i = 0; i < arr.length; i++) {
document.write(`
<div style="height: ${arr[i]}px;">
<span>${arr[i]}</span>
<h4>第${i + 1}季度</h4>
</div>
`)
}
document.write(`</div>`)
</script>
10. 函数
10.1 为什么需要函数
function,是被设计为执行特定任务的代码块
说明:
函数可以把具有相同或相似逻辑的代码“包裹”起来,通过函数调用执行这些被“包裹”的代码逻辑,这么做的优势是有利于精简代码方便复用。
10.2 函数使用
函数的声明语法
function 函数名() {
函数体
}
- 函数名命名规范
- 和变量命名基本一致
- 尽量小驼峰式命名法
- 前缀应该为动词
- 命名建议:常用动词约定
| 动词 | 含义 |
| can |
判断是否可执行某个动作 |
| has |
判断是否含义某个值 |
| is |
判断是否为某个值 |
| get |
获取某个值 |
| set |
设置某个值 |
| load |
加载某些数据 |
函数的调用语法
// 函数调用,这些函数体内的代码逻辑会被执行
函数名()
- 注意:声明(定义)的函数必须调用才会真正被执行,使用()调用函数
- 我们曾经使用的 alert(),parseInt()这种名字后面跟小括号的本质都是函数的调用
函数体
- 函数体是函数的构成部分,它负责将相同或相似代码“包裹”起来,直到函数调用时函数体内的代码才会被执行。函数的功能代码都要写在函数体当中。
// 打招呼
function sayHi() {
console.log('嗨~')
}
sayHi()
// 封装一个函数,计算两个数的和
function getSum() {
let num1 = 10
let num2 = 20
document.write(`${num1 + num2}<br>`)
}
getSum()
// 封装一个函数,计算1-100之间所有数的和
function getSum100() {
let sum = 0
for (let i = 1; i <= 100; i++) {
sum += i
}
document.write(`1~100之间所有数的和为:${sum}`)
}
getSum100()
1. 为什么要有参数的函数
思考:这样的函数只能求 10 + 20,这个函数功能局限非常大
解决办法:把要计算的数字传到函数内
结论:
- 若函数完成功能需要调用者传入数据,那么就需要用有参数的函数
- 这样可以极大提高函数的灵活性
2. 有参数的函数声明和调用
声明语法
function 函数名(参数列表){
函数体
}
参数列表
- 传入数据列表
- 声明这个函数需要传入几个数据
- 多个数据用逗号隔开
调用语法
函数名(传递的参数列表)
- 调用函数时,需要传入几个数据就写几个,用逗号隔开
3. 形参和实参
- 形参:声明函数时写在函数名右边小括号里的叫形参(形式上的参数)
- 实参:调用函数时写在函数名右边小括号里的叫实参(实际上的参数)
- 形参可以理解为是在这个函数内声明的变量(比如 num1 = 10)实参可以理解为是给这个变量赋值
- 开发中尽量保持形参和实参个数一致
- 我们曾经使用过的 alert('打印'), parseInt('11'), Number('11') 本质上都是函数调用的传参
function getSum(num1, num2) {
document.write(`${num1 + num2}`)
}
function getSum100(start, end) {
let sum = 0
for (let i = start; i <= end; i++) {
sum += i
}
document.write(`${start},${end}之间所有数的和为:${sum}`)
}
getSum100(1, 100)
function getSum100(start, end) {
let sum = 0
// 如果调用的时候,我们没有传递实参,默认为0
start = start || 0
end = end || 0
for (let i = start; i <= end; i++) {
sum += i
}
document.write(`${start},${end}之间所有数的和为:${sum}`)
}
getSum100()
// 函数封装 - 求学生总分
// 传递过去的参数是一个数组
function getScore(arr) {
// 封装一个求和函数
let sum = 0
// 函数内部遍历数组求和
for (let i = 0; i < arr.length; i++) {
sum = sum + arr[i]
}
document.write(sum)
}
getScore([100, 100, 100, 100, 100])
10.3 函数返回值
1. 为什么要让函数有返回值
- 什么是函数
- 函数是被设计为执行特定任务的代码块
- 执行完特定任务之后,然后呢?
- 把任务的结果给我们
- 缺点:把计算后的结果处理方式写死了,内部处理了
- 解决:把处理结果返回给调用者
- 有返回值函数的概念:
- 当调用某个函数,这个函数会返回一个结果出来
- 这就是有返回值的函数
2. 用return返回数据
当函数需要返回数据出去时,用return关键字
语法
return 数据
使用方法
function getSum(x, y) {
return x + y
}
let num = getSum(10, 30)
document.write(num)
function fn() {
return 20 // 相当于执行了 fn() = 20
}
fn() // 没有返回值,如果需要返回值:document.write(fn())
// 有时函数名字比较长
function getMyResult() {
return 20
}
document.write(getMyResult()) // 20
// 当我们想要调用时,可以:
let re = getMyResult()
document.write(re)
// 求和函数有返回值,这个函数就只是求和,把结果返回给我们就行了,这个函数不需要打印输出
function getSum(x, y) {
x = x || 0
y = y || 0
return x + y
}
let sum = getSum(1, 2)
// 什么时候需要它时,就打印输出
document.write(sum)
3. 用 return 返回数据
细节:
- 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
- 函数内部只能出现 1 次 return,并且 return 后面代码不会再被执行,所以 return 后面的数据不要换行写
- return 会立即结束当前函数
- 函数可以没有 return,这种情况函数默认返回值为 undefined
// 求数组中的最大值
function getArrMax(arr) {
// 声明一个max变量,把数组第一个值给max
let max = arr[0]
// 开始遍历数组并比较
for (let i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
}
// 返回这个最大值
return max
}
let re = getArrMax([2, 5, 3, 9, 7, 8])
document.write(re)
// 使用 return 返回多个值
function getReturn(x, y) {
let plus = x + y
let minus = x - y
// return plus minus结果只返回一个值,因为return只能返回一个值
return [plus, minus]
}
let re = getReturn(10, 50)
document.write(`相加之后的结果:${re[0]}<br> 相减之后的结果:${re[1]}`)
求数组中的最大值和最小值
function getArrValue(arr) {
// 声明一个最大值和最小值变量,并把数组中的第一个值赋给它
let max = min = arr[0]
// 遍历数组,得到最大值和最小值
for (let i = 1; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i]
}
if (min > arr[i]) {
min = arr[i]
}
/* 第二种:
max < arr[i] ? max = arr[i]:max
min > arr[i] ? min = arr[i]:min
*/
/* 第三种:
max = max < arr[i] ? arr[i]:max
min = min > arr[i] ? arr[i]:min
*/
}
// 返回最大值和最小值
return [max, min]
}
let value = getArrValue([20, 50, 30, 90, 40, 10])
document.write(`数组中的最大值:${value[0]},数组中的最小值:${value[1]}`)
// 求两个数中的最大值
let num1 = +prompt('请输入第一个数:')
let num2 = +prompt('请输入第二个数:')
// 比较函数,得出最大值
// return可以写多个,但是条件只能执行一个
function getMaxValue(num1, num2) {
/* if (num1 > num2) {
return num1
} else {
return num2
} */
return num1 > num2 ? num1 : num2
}
// 实参也可以放变量
let value = getMaxValue(num1, num2)
document.write(value)
10.4 作用域
1. 作用域概述
通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。
- 全局作用域
- 全局有效,作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件
- 局部作用域
- 局部有效,作用于函数内的代码环境,就是局部作用域。因为跟函数有关系,所以也称为函数作用域
- 块级作用域
- {}内有效,块作用域由 {} 包裹,if 语句和 for 语句里面的 {} 等
2. 变量的作用域
- 全局变量
- 函数外部 let 的变量
- 全局变量在任何区域都可以访问和修改
- 局部变量
- 函数内部 let 的变量
- 局部变量只能在当前函数内部访问和修改
- 块级变量
- {} 内部的 let 变量
- let 定义的变量,只能在块作用域里访问,不能跨块作用域里访问,不能跨块访问,也不能跨函数访问
3. 变量的作用域
变量有一个坑,特殊情况:
如果函数内部或者块级作用域内部,变量没有声明,直接赋值,也当全局变量看,但是强烈不推荐
但是有一种情况,函数内部的形参可以看做是局部变量。
4. 变量访问原则 - 作用域链
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链
10.5 匿名函数
1. 匿名函数
- 具名函数
- 声明:function fn() {}
- 调用:fn()
- 匿名函数
- function() {}
将匿名函数赋值给一个变量,并且通过变量名称进行调用,我们将这个称为函数表达式
语法:
let fn = function() {
// 函数体
}
调用:
fn() // 函数名
2. 立即执行函数
场景介绍:避免全局变量之间的污染
语法:
// 方式1
(function () {console.log(11)})();
// 方式2
(function () {console.log(11)}());
// 不需要调用,立即执行
- 注意:多个立即执行函数要用;隔开,要不然会报错
转换时间案例 {用户输入秒数,可以自动转换为时分秒}
// 1. 用户输入总秒数
let seconds = +prompt('请输入秒数:')
// 2. 计算时分秒(封装函数)里面包含数字补0
function getTimes(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
return `计算之后的时间是${h}小时${m}分${s}秒`
}
// 3. 打印输出
let str = getTimes(seconds)
document.write(str)
计算公式:计算时分秒
小时:h = parseInt(总秒数 / 60 / 60 % 24)
分钟:m = parseInt(总秒数 / 60 % 24)
秒数:h = parseInt(总秒数 % 60)
// 当不知道有多少实参传过来时
function fn() {
// arguments 函数内有效,表现形式为伪数组
// 伪数组比真数组少了一些pop() push()等方法
console.log(arguments)
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
console.log(sum)
}
fn(1, 2, 3)
/* // 初:在用户没有传值的时候,会返回0
function fn(x, y) {
x = x || 0
y = y || 0
document.write(x + y)
}
fn() */
// 高:
// x 和 y 可以看做是 函数内部的局部变量
// 调用的时候会有个内部判断是否有参数传递过来
// 没有参数 则执行 x = 0
// 有参数,则执行实参赋值
function fn(x = 0, y = 0) {
document.write(x + y)
}
fn() // 0
fn(6, 5) // 11
11. 对象
11.1 什么是对象
对象(object):JavaScript里的一种数据类型
可以理解为是一种无序的数据集合
用来 描述某个事物,例如描述一个人
- 人有姓名、年龄、性别等信息、还有吃饭睡觉打代码等功能
- 如果用多个变量保存则比较散,用对象比较统一
比如描述班主任信息:
- 静态特征(姓名、年龄、身高、性别、爱好) => 可以使用数字,字符串,数组,布尔类型等表示
- 动态行为(点名,唱,跳,rap)=> 使用函数表示
11.2 对象使用
1. 对象声明语法
let 对象名 = {}
例如:
// 声明了一个person的对象
let person = {}
2. 对象由属性和方法组成
- 属性:信息或叫特征(名词)。比如 手机尺寸、颜色、重量等......
- 方法:功能或叫行为(动词)。比如 手机打电话、发短信、玩游戏......
let 对象名 = {
属性名:属性值,
方法名:函数
}
3. 属性
数据描述性的信息称为属性,如人的姓名、身高、年龄、性别等,一般是名词性的。
let person = {
uname: 'andy',
age: 18,
sex: '男'
}
- 属性都是成对出现的,包括属性名和值,它们之间使用英文 : 分隔
- 多个属性之间使用英文 , 分隔
- 属性就是依附在对象上的变量(外面是变量,对象内是属性)
- 属性名可以使用"" 或 '' ,一般情况下省略,除非名称遇到特殊符号如空格、中横线等
4. 属性访问
声明对象,并添加了若干属性后,可以使用 . 或 [] 获得对象中属性对应的值,我们称之为属性访问。
简单理解就是获得对象里面的属性值
let person = {
name: 'andy',
age: 18,
sex: '男'
}
console.log(person.name)
console.log(person.age)
let person = {
name: 'andy',
age: 18,
sex: '男'
}
console.log(person['name'])
console.log(person['age'])
5. 对象中的方法
数据行为性的信息称为方法,如跑步、唱歌等,一般是动词性的,其本质是函数
let person = {
name: 'andy',
sayHi: function() {
document.write('hi~~~')
}
}
- 1. 方法是由方法名和函数两部分构成,它们之间使用 : 分隔
- 2. 多个属性之间使用英文 , 分隔
- 3. 方法是依附在对象中的函数
- 4. 方法名可以使用 "" 或 '',一般情况下省略,除非名称遇到特殊符号如空格、中横线等
6. 对象中的方法访问
声明对象,并添加了若干方法后,可以使用 . 调用对象中函数,我们称之为方法调用
let person = {
name: 'andy',
sayHi: function() {
document.write('hi~~~')
}
}
// 对象名.方法名()
person.sayHi()
注意:千万别忘了给方法名后面加小括号
let person = {
name: 'andy',
sayHi: function() {
document.write('hi~~~')
}
}
// 对象名.方法名()
person.sayHi()
11.3 操作对象
对象本质是无序的数据集合,操作数据无非就是 增 删 改 查 语法:
- 查询对象
- 对象.属性 或 对象['属性']
- 对象.方法()
- 重新赋值
- 对象.属性 = 值
- 对象.方法 = function() {}
- 对象添加新的数据
- 对象名.新属性名 = 新值
- 删除对象中属性
- delete 对象名.属性名
let obj = {
uname: '小明',
age: 18
}
console.log(obj.age)
// 修改:对象.属性 = 新值
obj.age = 81
console.log(obj)
// 新增一个属性,js可以非常方便的动态新增属性或方法
obj.sex = '男'
// 先去对象里面找是否有sex这个属性,如果有则更新值修改,没有则新增这个属性
obj.sing = function() {
console.log('hi~~~')
}
console.log(obj)
// 删除
delete obj.uname
console.log(obj)
11.4 遍历对象
- 对象没有像数组一样的length属性,所以无法确定长度
- 对象里面是无序的键值对,没有规律。不像数组里面有规律的下标
可以利用for in遍历对象
let obj = {
uname: '小明',
age: 18,
sex: '男'
}
for (let k in obj) {
console.log(k) // 打印属性名
console.log(obj[k]) // 打印属性值
}
<script>
let students = [{
name: '小明',
age: 18,
genter: '男',
hometown: '河北省'
}, {
name: '小红',
age: 19,
genter: '女',
hometown: '河南省'
}, {
name: '小刚',
age: 20,
genter: '男',
hometown: '山西省'
}, {
name: '小蓝',
age: 21,
genter: '女',
hometown: '山东省'
}]
// 得到小明的名字
// console.log(students[0]) // {name: "小明", age: 18, genter: "男", hometown: "河北省"}
// console.log(students[0].name); // 小明
for (let i = 0; i < students.length; i++) {
console.log(students[i].name)
console.log(students[i].hometown)
}
</script>
下面代码运行:

<style>
table {
width: 600px;
text-align: center;
}
table,
th,
td {
border: 1px solid #ccc;
border-collapse: collapse;
}
caption {
font-style: 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>
<script>
// 第一步:打印头部和尾部
let students = [{
name: '小明',
age: 18,
gender: '男',
hometown: '河北省'
}, {
name: '小红',
age: 19,
gender: '女',
hometown: '河南省'
}, {
name: '小丽',
age: 20,
gender: '男',
hometown: '山西省'
}, {
name: '小刚',
age: 21,
gender: '女',
hometown: '山东省'
}]
document.write(`
<table>
<tbody>
<caption>学生列表</caption>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>家乡</th>
</tr>
`)
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>
`)
}
document.write(`
</tbody>
</table>
`)
</script>
11.5 内置对象
1. 内置对象是什么
- JavaScript内部提供的对象,包含各种属性和方法给开发者调用
- 思考:我们之间用过内置对象吗?
- document.write()
- console.log()
2. 内置对象Math
- Math对象是JavaScript提供的一个“数学高手”对象
- 提供了一系列做数学运算的方法
- 可以通过MDN查询
3. 生成任意范围随机数
- 生成N - M之间的随机数(生成的随机数包含N与M)
- Math.floor(Math.random() * (M - N + 1)) + N
// 封装一个函数,求💖到💖的随机数
function getRandom() {
Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1, 10)
console.log(random)
// 随机点名
// 随机数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '刘备', '曹操']
let random = getRandom(0, arr.length - 1)
document.write(arr[random])
// 随机点名
// 随机数
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
// 声明一个数组
let arr = ['赵云', '黄忠', '关羽', '张飞', '刘备', '曹操']
let random = getRandom(0, arr.length - 1)
document.write(arr[random])
// 随机点名案例改进:随机显示一个名字到页面中,不能重复显示
// arr.splice(从哪里开始删,删几个)
arr.splice(random, 1)
console.log(arr)
// 猜数字游戏
/*
程序随机生成1~10之间的数字,用户输入一个数字
1. 如果大于该数字,就提示,数字猜大了,继续猜
2. 如果小于该数字,就提示,数字猜小了,继续猜
3. 如果猜对了,就提示猜对了,程序结束
*/
/* 分析:
1. 利用随机数生成一个数字
2. 需要一直猜,所以需要不断的循环
3. 用户输入,如果猜对了,就退出条件,用while循环合适
4. 内部判断可以用多分支语句
*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min
}
let random = getRandom(1, 10)
while (true) {
let num = +prompt('请输入1~10之间的随机数')
if (random < num) {
alert('猜大了')
} else if (random > num) {
alert('猜小了')
} else {
alert('猜对了')
break // break 退出循环 return退出函数
}
}
拓展 - 术语解释
| 术语 | 解释 | 举例 |
|---|---|---|
| 关键字 | 在JavaScript中有特殊意义的词汇 | let、var、function、if、else、switch、case、break |
| 保留字 | 在目前的JavaScript中没意义,但未来可能会具有特殊意义的词汇 | int、short、long、char |
| 标识(标识符) | 变量名、函数名的另一种叫法 | 无 |
| 表达式 | 能产生值的代码,一般配合运算符出现 | 10 + 3、age >= 18 |
| 语句 | 一句代码也称之为一条语句,一般按用途还会分类:输出语句、声明语句、分支语句 | 无 |
拓展 - 基本数据类型和引用数据类型
简单类型又叫做基本数据类型或者值类型,复杂类型又叫做引用类型
- 值类型:简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型
- string,number,boolean,undefined,null
- 引用类型:复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型
- 通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等
拓展 - 基本数据类型和引用数据类型
堆栈空间分配区别:
1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;
简单数据类型存放到栈里面
2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。
引用数据类型存放到堆里面




浙公网安备 33010602011771号