文章目录
-
- 前言
- 一、JavaScript基本概念
- 二、JavaScript基本语法
- 三、JavaScript数据类型
- [四、JavaScript 运算符](#四、JavaScript 运算符)
- 五、JavaScript流程控制
- 六、JavaScript数组
- 七、JavaScript函数
- [八、DOM 文档对象模型](#八、DOM 文档对象模型)
- [九、JavaScript 事件](#九、JavaScript 事件)
- 十、JavaScript操作元素
- [十一、JavaScript BOM](#十一、JavaScript BOM)
-
- 1、什么是BOM
- [2、BOM 的构成](#2、BOM 的构成)
- [3、顶级对象 window](#3、顶级对象 window)
- [4、window 对象的常见事件](#4、window 对象的常见事件)
- 十二、JavaScript定时器
-
- [1、setTimeout () 炸弹定时器](#1、setTimeout () 炸弹定时器)
- [2、setInterval () 闹钟定时器](#2、setInterval () 闹钟定时器)
- 3、案例:发送短信倒计时
- [十三、JavaScript this 指向问题](#十三、JavaScript this 指向问题)
-
- [1、全局作用域中 this 指向](#1、全局作用域中 this 指向)
- [2、普通函数中 this 指向](#2、普通函数中 this 指向)
- [3、事件处理函数中 this 指向](#3、事件处理函数中 this 指向)
- [4、定时器回调函数中 this 指向](#4、定时器回调函数中 this 指向)
- [5、箭头函数中 this 指向](#5、箭头函数中 this 指向)
- 结语
前言
JavaScript是前端开发的核心三剑客之一,也是赋予网页交互能力的"灵魂"语言。接下来我将从零基础视角出发,详细拆解JavaScript的核心知识点,每个模块搭配基础易懂的代码实例,希望能够更好地帮助你快速入门并掌握实用技能。
一、JavaScript基本概念
1、JavaScript是什么?
JavaScript(简称JS)是一种解释型、弱类型、面向对象的脚步语言,无需编译,直接由浏览器解析执行,最初用于增强网页交互效果,如今已经广泛应用于前端开发、后端开发(Node.js)、移动端开发等多个领域。
2、JavaScript的作用
- 网页交互:实现按钮点击、表单验证、轮播图切换、弹窗提示等动态效果;
- 数据处理:对页面数据进行计算、筛选、格式化等操作;
- DOM/BOM操作:控制网页元素的样式和结构,操作浏览器窗口、地址栏等;
- 异步请求:实现无刷新加载数据(如 Ajax),提升用户体验。
3、HTML/CSS/JS的关系
- HTML:负责网页的结构,定义页面有哪些元素(如标题、按钮、图片);
- CSS:负责网页的样式,美化元素的外观(如颜色、大小、布局);
- JavaScript:负责网页的行为,控制元素的交互和动态变化,实现"静态页面"到"动态网页"的转变。
三者分工明确,共同构成完整的网页开发技术栈。
4、JS的组成
JavaScript由三个核心部分组成,缺一不可:
- ECMAScript:JS的语法标准,规定了变量、数据类型、运算符、函数等基础语法规则;
- DOM(文档对象模型):提供操作网页元素的API,可实现对页面结构的增删改查;
- BOM(浏览器对象模型):提供操作浏览器的API,可实现窗口控制、定时器、网络请求等功能。
5、JavaScript的书写方式
与CSS类似,JS也有三种书写方式:
| 书写方式 | 写法 | 适用场景 |
|---|---|---|
| 行内式 | <标签 οnclick="JS代码"> | 临时给单个元素绑定简单事件(不推荐大量使用) |
| 内嵌式 | <script>标签包裹JS代码,放在<body>底部或者上部 |
单个页面的简单交互(小型项目) |
| 外联式 | <script src="JS文件路径.js"></script> |
多个页面共享JS逻辑(推荐大型项目) |
6、JavaScript注释
注释用于标注代码含义,不被浏览器执行,分为两种:
- 单行注释:
// 注释内容(快捷键:Ctrl+/),用于注释单行代码; - 多行注释:
/* 注释内容 */(快捷键:Ctrl+/),用于注释多行代码或代码块。
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS基本概念</title>
</head>
<body>
<!-- 行内式:点击按钮弹出提示 -->
<button onclick="alert('行内式JS')">点击我</button>
<!-- 内嵌式:script标签放在body底部 -->
<script>
// 单行注释:这是内嵌式JS代码
/*
* 多行注释:
* 弹出欢迎提示
* 这是基础交互效果
*/
alert('欢迎学习JavaScript!');
</script>
<!-- 外联式:引入外部JS文件(需新建index.js) -->
<script src="index.js"></script>
</body>
</html>
index.js文件内容:
javascript
// 外联式JS代码:在控制台打印信息
console.log('这是外部JS文件中的代码');
运行效果如下:


二、JavaScript基本语法
1、JavaScript输入输出语句
输入输出是JS与用户交互的基础,新手需掌握4种常用语句:
| 语句 | 作用 | 示例 |
|---|---|---|
| alert('内容') | 浏览器弹出提示框(输出) | alert('Hello JS') |
| prompt('提示文字') | 浏览器弹出输入框,获取用户输入(输入) | let name = prompt('请输入你的名字') |
| console.log('内容') | 在浏览器控制台打印信息(调试/输出) | console.log('调试信息') |
| confirm('提示文字') | 浏览器弹出确认框,返回布尔值(输入) | let isAgree = confirm('是否同意协议') |
2、变量
变量是用于存储数据的容器,相当于给数据起一个名字,方便后续调用和修改。JS 中用 let 关键字声明变量(ES6 推荐,支持块级作用域),早期用 var(不推荐,存在变量提升等问题)。
3、变量的使用
变量的使用分为 "声明" 和 "赋值" 两步,可合并书写:
javascript
// 1. 先声明,后赋值
let age; // 声明变量age
age = 18; // 给变量age赋值为18
// 2. 声明并赋值(常用)
let name = '张三';
// 3. 同时声明多个变量
let gender = '男', height = 180;
// 4. 修改变量的值
name = '李四';
4、变量命名规范
变量命名需遵循一定规则,否则会报错或降低可读性:
- 必须遵守:
- 由字母(a-z/A-Z)、数字(0-9)、下划线(_)、美元符号($)组成;
- 不能以数字开头;
- 不能使用JS关键字(如let、var、if、for等);
- 区分大小写(如age和Age是两个不同变量)
- 推荐遵循:
- 采用驼峰命名法:首字母小写,后续单词首字母大写(如userName、userAge);
- 变量名需语义化,见名之意(如用age存年龄,不用a存年龄)。
代码实例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS基础语法</title>
</head>
<body>
<script>
// 输入:获取用户姓名
let userName = prompt('请输入你的姓名:');
// 输入:获取用户年龄
let userAge = prompt('请输入你的年龄:');
// 输出:弹窗显示用户信息
alert('你的姓名是:' + userName + ',你的年龄是:' + userAge);
// 输出:控制台打印用户信息
console.log('姓名:', userName, '年龄:', userAge);
// 修改变量值
userAge = Number(userAge) + 1;
alert('明年你的年龄是:' + userAge);
</script>
</body>
</html>
运行效果如下:






三、JavaScript数据类型
1、数据类型简介
JS是弱类型语言,变量声明时无需指定数据类型,赋值后自动确定类型。数据类型决定了数据的存储方式和运算规则,是JS语法的基础。
2、数据类型的分类
JS数据类型分为两大类:
(1)基本数据类型(简单数据类型)
共6种,存储在栈内存中:
| 数据类型 | 说明 | 示例 |
|---|---|---|
| String(字符串) | 文本数据,用单引号/双引号包裹 | '张三'、"Hello"、' '(空字符串) |
| Number(数字) | 整数或小数,支持正数、负数、0 | 18/3。14、-5、NaN(非数字) |
| Boolean(布尔) | 只有两个值:true(真)、false(假) | let isOk = true |
| Undefined(未定义) | 变量声明未赋值时的类型 | let a; |
| Null(空值) | 表示变量的值为空(指向空对象) | let b = null; |
(2)引用数据类型(复杂数据类型)
包括对象(Object)、数组(Array)、函数(Function)等,存储在堆内,栈内存仅存储其引用地址。
3、获取变量数据类型
用typeof 关键字可获取变量的数据类型,返回字符串类型:
javascript
let str = 'Hello';
console.log(typeof str); // 输出:string
let num = 18;
console.log(typeof num); // 输出:number
let isTrue = true;
console.log(typeof isTrue); // 输出:boolean
let a;
console.log(typeof a); // 输出:undefined
let b = null;
console.log(typeof b); // 输出:object(特殊情况)
4、数据类型转换
开发中常需要转换数据类型,核心分为 "转为字符串""转为数字""转为布尔" 三种:
(1)转为字符串
| 方法 | 示例 |
|---|---|
| 变量+''(隐式转换,推荐) | let num = 18; let str = num + ''; |
| String(变量)(显式转换) | let num = 18; let str = String(num); |
| 变量.toString()(显式转换,null/undefined 不可用) | let num = 18; let str = num.toString(); |
(2)转为数字
| 方法 | 示例 | 说明 |
|---|---|---|
| Number(变量)(显式转换) | Number('18') → 18;Number('18a') → NaN | 纯数字字符串转为对应数字,非纯数字转为 NaN |
| parseInt(变量)(显式转换) | parseInt('18.99') → 18;parseInt('18a') → 18 | 提取整数部分,忽略小数和非数字字符 |
| parseFloat(变量)(显式转换) | parseFloat('18.99') → 18.99;parseFloat('18a') → 18 | 提取小数部分,忽略非数字字符 |
| 变量 - 0 / * 1(隐式转换) | '18' - 0 → 18;'18.99' * 1 → 18.99 | 简单快捷,推荐使用 |
(3)转为布尔
用 Boolean(变量) 转换,只有 6 种值会转为 false,其余均为 true:
- false、0、''(空字符串)、NaN、undefined、null
javascript
console.log(Boolean(0)); // false
console.log(Boolean('')); // false
console.log(Boolean(18)); // true
console.log(Boolean('Hello')); // true
代码实例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS数据类型</title>
</head>
<body>
<script>
// 1. 定义不同类型的变量
let str = 'JavaScript';
let num = 2024;
let isStudy = true;
let unDef;
let nul = null;
// 2. 获取变量类型
console.log('str的类型:', typeof str);
console.log('num的类型:', typeof num);
console.log('isStudy的类型:', typeof isStudy);
console.log('unDef的类型:', typeof unDef);
console.log('nul的类型:', typeof nul);
// 3. 数据类型转换
// 字符串转数字
let strNum = '18.99';
let num1 = Number(strNum);
let num2 = parseInt(strNum);
let num3 = parseFloat(strNum);
console.log('Number转换:', num1); // 18.99
console.log('parseInt转换:', num2); // 18
console.log('parseFloat转换:', num3); // 18.99
// 数字转字符串
let newStr = num + '';
console.log('数字转字符串:', newStr, typeof newStr); // "2024" string
// 转为布尔
console.log('0转为布尔:', Boolean(0)); // false
console.log('"abc"转为布尔:', Boolean("abc")); // true
</script>
</body>
</html>
运行效果如下:

注:要查看运行的效果需要点击鼠标右键点击检查,就可以在控制台看到运行的效果。
四、JavaScript 运算符
运算符用于对数据进行运算或判断,是流程控制的基础,需掌握 6 类核心运算符:
1、算术运算符
用于进行数学运算,常用运算符如下:
| 运算符 | 作用 | 示例 |
|---|---|---|
| + | 加法/字符串拼接 | 10 + 20 → 30;'10' + 20 → '1020' |
| - | 减法 | 20 - 10 → 10;'20' - 10 → 10(隐式转数字) |
| * | 乘法 | 10 * 20 → 200 |
| / | 除法 | 20 / 10 → 2 |
| % | 取余(求余数) | 21 % 10 → 1;20 % 10 → 0(判断奇偶 / 整除) |
注意:+ 两边有字符串时,会进行字符串拼接,而非加法运算。
2、递增和递减运算符
用于快速让变量加1或减1,分为前置或后置两种:
| 运算符 | 写法 | 说明 |
|---|---|---|
| 前置递增 | ++num | 先让变量加1,再使用变量的值 |
| 后置递增 | num++ | 先使用变量的值,再让变量加1 |
| 前置递减 | --num | 先让变量减1,再使用变量的值 |
| 后置递减 | num-- | 先使用变量的值,再让变量减1 |
| 示例: |
javascript
let num = 10;
console.log(++num); // 11(先加1,再打印)
console.log(num); // 11
let num2 = 10;
console.log(num2++); // 10(先打印,再加1)
console.log(num2); // 11
3、比较运算符
用于比较两个值的大小或是否相等,返回布尔值(true/false):
| 运算符 | 作用 | 示例 |
|---|---|---|
| > | 大于 | 10 > 5 → true |
| < | 小于 | 10 < 5 → false |
| >= | 大于等于 | 10 >= 10 → true |
| <= | 小于等于 | 10 <= 5 → false |
| == | 相等(只比较值,不比较类型,隐式转换) | 10 == '10' → true |
| === | 全等(既比较值,也比较类型,推荐使用) | 10 === '10' → false |
| != | 不相等(不比较类型) | 10 != '10' → false |
| !== | 不全等(比较类型) | 10 !== '10' → true |
注意:开发中优先使用 === 和 ! ==,避免隐式转换导致的错误。
4、逻辑运算符
用于连接多个条件,进行逻辑判断,返回布尔值:
| 运算符 | 名称 | 作用 | 示例 |
|---|---|---|---|
&& |
逻辑与(并且) | 所有条件为真,结果才为真 | 10 > 5 && 8 > 3 → true |
| | | 逻辑或 | 只要有一个条件为真,结果就为真 | 10 >5 | 8 < 3→ true |
! |
逻辑非(取反) | 对条件结果取反 | !true → false;!false → true |
5、赋值运算符
用于给变量赋值,常用如下:
| 运算符 | 作用 | 示例 | 等价于 |
|---|---|---|---|
| = | 直接赋值 | let num = 10 | - |
| += | 加后赋值 | num += 5 | num = num +5 |
| -= | 减后赋值 | num -= 5 | num = num - 5 |
| *= | 乘后赋值 | num *= 5 | num = num * 5 |
| /= | 除后赋值 | num /= 5 | num = num / 5 |
| %= | 取余后赋值 | num %= 5 | num = num % 5 |
6、运算符优先级
当多个运算符同时出现时,遵循 "先算谁后算谁" 的规则,优先级从高到低大致如下:
- 括号 ()(优先级最高,可手动改变运算顺序)
- 递增 / 递减运算符 ++ --
- 算术运算符(* / % 高于 + -)
- 比较运算符 > < >= <=
- 相等运算符
==!====!== - 逻辑运算符(&& 高于 ||)
- 赋值运算符 = += -= 等
- 逗号 ,(优先级最低)
示例:
javascript
let result = 10 + 20 * 3; // 先算20*3=60,再算10+60=70
console.log(result); // 70
let result2 = (10 + 20) * 3; // 先算括号内10+20=30,再算30*3=90
console.log(result2); // 90
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS运算符</title>
</head>
<body>
<script>
// 1. 算术运算符
let a = 10, b = 3;
console.log('加法:', a + b); // 13
console.log('减法:', a - b); // 7
console.log('乘法:', a * b); // 30
console.log('除法:', a / b); // 3.333...
console.log('取余:', a % b); // 1
// 2. 递增/递减运算符
let num = 5;
console.log('前置递增:', ++num); // 6
console.log('后置递增:', num++); // 6
console.log('递增后:', num); // 7
// 3. 比较运算符
console.log('全等:', 10 === '10'); // false
console.log('大于等于:', 10 >= 8); // true
// 4. 逻辑运算符
let score1 = 90, score2 = 80;
let isExcellent = score1 >= 90 && score2 >= 90;
console.log('是否优秀:', isExcellent); // false
// 5. 赋值运算符
let x = 20;
x += 5;
console.log('赋值后:', x); // 25
// 6. 运算符优先级
let res = (10 + 5) * 2 - 8 / 2;
console.log('运算结果:', res); // 26
</script>
</body>
</html>
运行效果:

五、JavaScript流程控制
流程控制用于控制代码的执行顺序,分为 "分支流程控制" 和 "循环流程控制" 两大类,是实现复杂逻辑的核心。
1、if 分支流程控制
根据条件判断是否执行某段代码,分为单分支、双分支、多分支三种:
(1)单分支(满足条件才执行)
javascript
// 语法:if (条件) { 满足条件执行的代码 }
let score = 85;
if (score >= 60) {
console.log('考试及格');
}
(2)双分支(二选一执行)
javascript
// 语法:if (条件) { 满足条件执行的代码 } else { 不满足条件执行的代码 }
let score = 55;
if (score >= 60) {
console.log('考试及格');
} else {
console.log('考试不及格');
}
(3)多分支(多选一执行)
javascript
// 语法:if (条件1) { 执行代码1 } else if (条件2) { 执行代码2 } ... else { 都不满足执行的代码 }
let score = 92;
if (score >= 90) {
console.log('优秀');
} else if (score >= 80) {
console.log('良好');
} else if (score >= 60) {
console.log('及格');
} else {
console.log('不及格');
}
2、switch 分支流程控制
用于固定值的多分支判断(如判断性别、月份、选项等),语法更简洁:
javascript
// 语法:
// switch (表达式) {
// case 值1: 执行代码1; break;
// case 值2: 执行代码2; break;
// ...
// default: 都不满足执行的代码;
// }
let week = 3;
switch (week) {
case 1:
console.log('星期一');
break; // 跳出switch,防止穿透
case 2:
console.log('星期二');
break;
case 3:
console.log('星期三');
break;
default:
console.log('其他日期');
}
注意:break不可省略(除非需要穿透效果),否则会继续执行后续case的代码。
3、for循环
用于已知循环次数的场景(如遍历数组、重复执行固定次数),语法最常用:
javascript
// 语法:for (初始化变量; 循环条件; 更新变量) { 循环体代码 }
// 示例:循环打印1-5
for (let i = 1; i <= 5; i++) {
console.log(i); // 依次打印1、2、3、4、5
}
// 示例:计算1-100的和
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log('1-100的和:', sum); // 5050
4、while循环
用于未知循环次数的场景,先判断条件,再执行循环体:
javascript
// 语法:while (循环条件) { 循环体代码; 更新变量 }
// 示例:循环打印1-5
let i = 1;
while (i <= 5) {
console.log(i);
i++; // 必须更新变量,否则会无限循环
}
5、do-while 循环
先执行一次循环体,再判断条件(无论条件是否满足,至少执行一次):
javascript
// 语法:do { 循环体代码; 更新变量 } while (循环条件);
// 示例:循环打印1-5
let i = 1;
do {
console.log(i);
i++;
} while (i <= 5);
6、continue 和 break
用于控制循环的执行流程:
- continue:跳过本次循环,继续执行下一次循环;
javascript
// 示例:打印1-5,跳过3
for (let i = 1; i <= 5; i++) {
if (i === 3) {
continue; // 跳过i=3的循环
}
console.log(i); // 打印1、2、4、5
}
- break:立即终止整个循环,跳出循环体;
javascript
// 示例:打印1-5,遇到3终止循环
for (let i = 1; i <= 5; i++) {
if (i === 3) {
break; // 终止循环
}
console.log(i); // 打印1、2
}
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS流程控制</title>
</head>
<body>
<script>
// 1. if多分支:判断成绩等级
let score = prompt('请输入你的成绩(0-100)');
score = Number(score);
if (score >= 90 && score <= 100) {
alert('优秀');
} else if (score >= 80 && score < 90) {
alert('良好');
} else if (score >= 60 && score < 80) {
alert('及格');
} else if (score >= 0 && score < 60) {
alert('不及格');
} else {
alert('请输入有效的成绩!');
}
// 2. switch:判断星期
let week = prompt('请输入星期数(1-7)');
week = Number(week);
switch (week) {
case 1: alert('星期一'); break;
case 2: alert('星期二'); break;
case 3: alert('星期三'); break;
case 4: alert('星期四'); break;
case 5: alert('星期五'); break;
case 6: alert('星期六'); break;
case 7: alert('星期日'); break;
default: alert('请输入1-7的数字!');
}
// 3. for循环:计算1-10的乘积
let product = 1;
for (let i = 1; i <= 10; i++) {
product *= i;
}
console.log('1-10的乘积:', product); // 3628800
// 4. while循环:求100以内的偶数和
let evenSum = 0;
let j = 1;
while (j <= 100) {
if (j % 2 === 0) {
evenSum += j;
}
j++;
}
console.log('100以内偶数和:', evenSum); // 2550
// 5. continue:跳过奇数
for (let k = 1; k <= 10; k++) {
if (k % 2 !== 0) {
continue;
}
console.log('偶数:', k); // 2、4、6、8、10
}
</script>
</body>
</html>
运行效果如下:





六、JavaScript数组
数组是用于存储多个数据的集合,可以存储不同类型的数据(如数字、字符串、对象等),方便批量管理和操作数据。
1、数组的概念
数组就像一个 "储物柜",每个格子对应一个数据,每个格子有唯一的 "索引"(从 0 开始),通过索引可以快速访问对应的数据。
2、创建数组
JS 中创建数组有两种常用方式:
(1)字面量方式(推荐,简洁高效)
javascript
// 语法:let 数组名 = [数据1, 数据2, 数据3, ...];
let arr1 = [10, 20, 30, 40]; // 数字数组
let arr2 = ['张三', '李四', '王五']; // 字符串数组
let arr3 = [18, '张三', true]; // 混合类型数组
let arr4 = []; // 空数组
(2)new Array () 方式
javascript
// 语法:let 数组名 = new Array(数据1, 数据2, ...);
let arr5 = new Array(10, 20, 30); // 等同于 [10,20,30]
let arr6 = new Array(3); // 创建长度为3的空数组(每个元素为undefined)
3、获取数组中的元素
通过 "数组名 [索引]" 获取数组元素,索引从 0 开始,最大索引为 "数组长度 - 1":
javascript
let arr = ['张三', '李四', '王五'];
console.log(arr[0]); // 第一个元素:张三
console.log(arr[1]); // 第二个元素:李四
console.log(arr[2]); // 第三个元素:王五
// 数组长度:数组名.length
console.log(arr.length); // 3
4、遍历数组
遍历数组即依次访问数组的每个元素,常用 for 循环实现:
javascript
let arr = [10, 20, 30, 40];
// 遍历数组
for (let i = 0; i < arr.length; i++) {
console.log('第' + (i+1) + '个元素:', arr[i]);
}
// 输出:
// 第1个元素:10
// 第2个元素:20
// 第3个元素:30
// 第4个元素:40
5、数组中新增元素
数组是动态的,可通过两种方式新增元素:
(1)通过索引新增(适用于已知索引)
javascript
let arr = [10, 20, 30];
arr[3] = 40; // 给索引3新增元素
arr[4] = 50;
console.log(arr); // [10,20,30,40,50]
(2)通过 push () 方法(在数组末尾新增,推荐)
javascript
let arr = [10, 20, 30];
arr.push(40); // 末尾新增一个元素
arr.push(50, 60); // 末尾新增多个元素
console.log(arr); // [10,20,30,40,50,60]
(3)通过 unshift () 方法(在数组开头新增)
javascript
let arr = [10, 20, 30];
arr.unshift(0); // 开头新增一个元素
arr.unshift(-20, -10); // 开头新增多个元素
console.log(arr); // [-20,-10,0,10,20,30]
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS数组</title>
</head>
<body>
<script>
// 1. 创建数组
let students = ['张三', '李四', '王五', '赵六'];
// 2. 获取数组元素和长度
console.log('第一个学生:', students[0]);
console.log('学生总数:', students.length);
// 3. 遍历数组:打印所有学生
console.log('班级学生列表:');
for (let i = 0; i < students.length; i++) {
console.log(i+1 + '.' + students[i]);
}
// 4. 新增元素
students.push('孙七'); // 末尾新增
students.unshift('周八'); // 开头新增
console.log('新增后的学生列表:', students);
// 5. 案例:计算数组元素的和
let nums = [1, 2, 3, 4, 5];
let sum = 0;
for (let i = 0; i < nums.length; i++) {
sum += nums[i];
}
console.log('数组元素和:', sum); // 15
</script>
</body>
</html>
运行效果如下:

七、JavaScript函数
函数是封装好的、可重复使用的代码块,用于实现特定功能,能减少代码冗余,提高开发效率。
1、函数的概念
函数就像一个 "工具",定义好后可以反复调用,传入不同的参数,得到不同的结果,核心优势是 "复用" 和 "解耦"。
2、函数的使用
函数的使用分为 "定义函数" 和 "调用函数" 两步:
(1)定义函数
javascript
// 语法:function 函数名() { 函数体代码(实现功能的代码) }
function sayHello() {
console.log('Hello JavaScript!');
}
(2)调用函数
javascript
// 语法:函数名();
sayHello(); // 调用函数,执行函数体代码,输出:Hello JavaScript!
sayHello(); // 可重复调用
3、函数封装
函数封装是将实现某一功能的代码块封装到函数中,让代码更简洁。例如,封装一个 "计算两个数之和" 的函数:
javascript
// 封装求和函数
function getSum() {
let num1 = 10;
let num2 = 20;
let sum = num1 + num2;
console.log('两数之和:', sum);
}
// 调用函数
getSum(); // 输出:两数之和:30
4、函数的参数
参数分为 "形参" 和 "实参",用于让函数更灵活,可接收外部传入的数据:
- 形参:定义函数时写在括号内的变量,用于接收实参;
- 实参:调用函数时写在括号内的数据,用于传递给形参。
javascript
// 语法:function 函数名(形参1, 形参2, ...) { 函数体代码 }
// 封装灵活的求和函数
function getSum(num1, num2) { // num1、num2是形参
let sum = num1 + num2;
console.log('两数之和:', sum);
}
// 调用函数:传入实参
getSum(10, 20); // 10、20是实参,输出:30
getSum(30, 40); // 输出:70
getSum(50, 60); // 输出:110
5、函数的返回值
函数的返回值是函数执行完成后,通过 return 关键字返回给调用者的数据,用于获取函数内部的执行结果:
javascript
// 语法:function 函数名(形参) { 执行代码; return 返回值; }
function getSum(num1, num2) {
let sum = num1 + num2;
return sum; // 返回求和结果
}
// 调用函数,接收返回值
let result = getSum(10, 20);
console.log('返回的和:', result); // 30
console.log('返回的和+10:', result + 10); // 40
注意:return 后面的代码不会执行,return 可不带返回值(用于终止函数执行)。
6、arguments 的使用
arguments 是函数内部的内置对象,用于接收所有实参,是一个伪数组(可遍历,有 length 属性,不能使用数组方法),适用于实参个数不确定的场景:
javascript
// 封装:计算任意个数的数字之和
function getTotal() {
let total = 0;
// 遍历arguments,累加所有实参
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
let res1 = getTotal(1, 2, 3);
console.log('1+2+3=', res1); // 6
let res2 = getTotal(1, 2, 3, 4, 5);
console.log('1+2+3+4+5=', res2); // 15
7、函数的两种声明方式
(1)函数声明式(常用,支持预解析)
javascript
// 语法:function 函数名(形参) { 函数体 }
function sayHi() {
console.log('Hi!');
}
sayHi();
(2)函数表达式(匿名函数赋值给变量,不支持预解析)
javascript
// 语法:let 变量名 = function(形参) { 函数体 };
let sayHi = function() {
console.log('Hi!');
};
sayHi(); // 调用时变量名后加括号
8、作用域
作用域指变量的有效范围,分为 "全局作用域" 和 "局部作用域":
(1)全局作用域
变量在
javascript
let globalVar = '全局变量';
function fn() {
console.log(globalVar); // 局部作用域可访问全局变量
}
fn(); // 输出:全局变量
(2)局部作用域
分为 "函数作用域" 和 "块级作用域":
- 函数作用域:变量在函数内部定义,仅在函数内部有效,函数执行完毕后销毁;
- 块级作用域:变量用 let/const 在 {} 内定义(如 if、for 循环),仅在 {} 内有效。
javascript
function fn() {
let localVar = '函数内局部变量';
console.log(localVar); // 函数内可访问
}
fn(); // 输出:函数内局部变量
// console.log(localVar); // 报错:变量未定义(函数外无法访问)
// 块级作用域
if (true) {
let blockVar = '块级变量';
console.log(blockVar); // 块内可访问
}
// console.log(blockVar); // 报错:变量未定义(块外无法访问)
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS函数</title>
</head>
<body>
<script>
// 1. 封装:判断一个数是否为偶数
function isEven(num) {
if (num % 2 === 0) {
return true;
} else {
return false;
}
}
let result1 = isEven(10);
console.log('10是否为偶数:', result1); // true
let result2 = isEven(11);
console.log('11是否为偶数:', result2); // false
// 2. arguments:求任意个数的最大值
function getMax() {
let max = arguments[0];
for (let i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
let max1 = getMax(3, 7, 2, 9, 5);
console.log('最大值:', max1); // 9
// 3. 函数表达式
let getMin = function() {
let min = arguments[0];
for (let i = 1; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
};
let min1 = getMin(3, 7, 2, 9, 5);
console.log('最小值:', min1); // 2
// 4. 作用域
let global = '全局变量';
function testScope() {
let local = '局部变量';
console.log(global); // 访问全局变量
console.log(local); // 访问局部变量
}
testScope();
// console.log(local); // 报错:local未定义
</script>
</body>
</html>
运行效果如下:

八、DOM 文档对象模型
DOM是浏览器提供的一套 API,用于操作网页的 HTML 结构,让 JS 可以动态修改页面的内容、样式和结构。
1、什么是DOM
DOM 将整个 HTML 文档看作一个 "文档对象",每个 HTML 标签都是一个 "元素节点",标签内的文字是 "文本节点",标签的属性是 "属性节点",通过这些节点对象,JS 可以实现对页面的增删改查。
2、DOM树
HTML 文档被浏览器解析后,会形成一棵 "DOM 树",树的根节点是 document(文档对象),所有其他节点都是 document 的子节点,层级分明:
- 根节点:document(代表整个 HTML 文档);
- /html 节点:根元素节点(document.documentElement);
- /head、/body 节点:/html 的子元素节点;
- 各类标签节点(如 div、p、a):/head 或 /body 的子元素节点;
- 文本节点:标签内的文字(如
<p>Hello</p>中的 "Hello"); - 属性节点:标签的属性(如
<a href="https://www.baidu.com">中的 "href")。
3、获取元素
操作元素的前提是 "获取元素",JS 提供了多种获取元素的方法,需掌握常用的 5 种:
(1)根据 ID 获取元素
javascript
// 语法:document.getElementById('id名');
// HTML:<div id="box">我是盒子</div>
let box = document.getElementById('box');
console.log(box); // 返回对应的元素对象
(2)根据标签名获取元素
javascript
// 语法:document.getElementsByTagName('标签名');
// HTML:<p>段落1</p> <p>段落2</p>
let pList = document.getElementsByTagName('p');
console.log(pList); // 返回伪数组,包含所有p标签元素
console.log(pList[0]); // 获取第一个p标签
(3)根据类名获取元素
javascript
// 语法:document.getElementsByClassName('类名');
// HTML:<div class="content">内容1</div> <div class="content">内容2</div>
let contentList = document.getElementsByClassName('content');
console.log(contentList); // 返回伪数组,包含所有class=content的元素
(4)根据选择器获取单个元素
javascript
// 语法:document.querySelector('CSS选择器');
// HTML:<div class="box">盒子1</div> <div class="box">盒子2</div>
let box = document.querySelector('.box'); // 获取第一个class=box的元素
let p = document.querySelector('#p1'); // 获取id=p1的元素
let span = document.querySelector('span'); // 获取第一个span标签
(5)根据选择器获取所有元素
javascript
// 语法:document.querySelectorAll('CSS选择器');
// HTML:<div class="box">盒子1</div> <div class="box">盒子2</div>
let boxList = document.querySelectorAll('.box');
console.log(boxList); // 返回伪数组,包含所有class=box的元素
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOM获取元素</title>
</head>
<body>
<div id="box">我是ID为box的盒子</div>
<p>我是段落1</p>
<p>我是段落2</p>
<div class="content">我是类为content的盒子1</div>
<div class="content">我是类为content的盒子2</div>
<span>我是span标签</span>
<script>
// 1. 根据ID获取
let box = document.getElementById('box');
console.log('根据ID获取:', box);
// 2. 根据标签名获取
let pList = document.getElementsByTagName('p');
console.log('根据标签名获取:', pList);
console.log('第一个p标签:', pList[0]);
// 3. 根据类名获取
let contentList = document.getElementsByClassName('content');
console.log('根据类名获取:', contentList);
// 4. 根据选择器获取单个元素
let firstContent = document.querySelector('.content');
console.log('选择器获取单个元素:', firstContent);
// 5. 根据选择器获取所有元素
let boxList = document.querySelectorAll('div');
console.log('选择器获取所有元素:', boxList);
</script>
</body>
</html>
运行效果如下:

九、JavaScript 事件
事件是用户与网页的交互行为(如点击按钮、鼠标移动、键盘按下等),JS 通过事件可以监听用户的操作,并执行对应的代码,实现交互效果。
1、事件概述
事件由 "事件源""事件类型""事件处理程序" 三部分组成(事件三要素),缺一不可。例如:"点击按钮弹出提示",其中按钮是事件源,点击是事件类型,弹出提示是事件处理程序。
2、事件三要素
- 事件源:触发事件的元素(如按钮、div、a 标签等);
- 事件类型:事件的触发方式(如点击 click、鼠标移入 mouseover、键盘按下 keydown 等);
- 事件处理程序:事件触发后执行的代码(通常是函数形式)。
3、执行事件的步骤
执行事件分为 3 步,是实现交互效果的标准流程:
- 获取事件源(找到触发事件的元素);
- 绑定事件类型(给事件源添加事件);
- 编写事件处理程序(事件触发后执行的代码)。
javascript
// 示例:点击按钮弹出提示
// 1. 获取事件源(按钮)
let btn = document.getElementById('btn');
// 2. 绑定事件类型(click)+ 3. 编写事件处理程序
btn.onclick = function() {
alert('按钮被点击了!');
};
4、 常见的鼠标事件
鼠标事件是最常用的事件类型,需掌握以下 6 种:
| 事件类型 | 触发事件 |
|---|---|
| onclick | 鼠标点击元素时触发 |
| onmouseover | 鼠标移入元素时触发 |
| onmouseout | 鼠标移出元素时触发 |
| onmousemove | 鼠标在元素内移动时触发 |
| onmousedown | 鼠标按下元素时触发 |
| onmouseup | 鼠标松开元素时触发 |
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS事件</title>
<style>
#box {
width: 200px;
height: 200px;
background-color: #f5f5f5;
margin: 20px 0;
}
</style>
</head>
<body>
<button id="btn">点击我</button>
<div id="box"></div>
<script>
// 1. 点击按钮弹出提示
let btn = document.getElementById('btn');
btn.onclick = function() {
alert('按钮被点击啦!');
};
// 2. 鼠标移入/移出盒子改变背景色
let box = document.getElementById('box');
// 鼠标移入
box.onmouseover = function() {
box.style.backgroundColor = '#ffcccc';
};
// 鼠标移出
box.onmouseout = function() {
box.style.backgroundColor = '#f5f5f5';
};
// 3. 鼠标在盒子内移动,显示鼠标位置
box.onmousemove = function(e) {
// e是事件对象,包含事件相关信息
box.innerText = `鼠标X:${e.clientX},鼠标Y:${e.clientY}`;
};
</script>
</body>
</html>
运行效果如下:



十、JavaScript操作元素
获取元素后,通过 JS 可以动态修改元素的内容、属性和样式,这是实现页面动态效果的核心。
1、改变元素内容(获取或设置)
有两种方式可以操作元素内容,适用于不同场景:
(1)innerText:获取 / 设置元素的纯文本内容(不解析 HTML 标签)
javascript
// HTML:<div id="box">原始内容</div>
let box = document.getElementById('box');
// 获取内容
console.log(box.innerText); // 输出:原始内容
// 设置内容
box.innerText = '修改后的纯文本内容';
// 设置HTML标签(不会解析,直接显示)
box.innerText = '<h3>这是h3标题</h3>'; // 页面显示:<h3>这是h3标题</h3>
(2)innerHTML:获取 / 设置元素的 HTML 内容(解析 HTML 标签,推荐)
javascript
// HTML:<div id="box">原始内容</div>
let box = document.getElementById('box');
// 获取内容
console.log(box.innerHTML); // 输出:原始内容
// 设置内容
box.innerHTML = '修改后的HTML内容';
// 设置HTML标签(会解析,显示对应样式)
box.innerHTML = '<h3>这是h3标题</h3>'; // 页面显示h3样式的标题
2、常用元素的属性操作
对于普通元素(如 img、a、div 等),可以直接通过 "元素对象。属性名" 获取或设置属性:
(1)操作 img 标签属性
javascript
// HTML:<img id="img" src="pic1.jpg" alt="图片1">
let img = document.getElementById('img');
// 获取属性
console.log(img.src); // 输出:图片路径
console.log(img.alt); // 输出:图片1
// 设置属性
img.src = 'pic2.jpg';
img.alt = '图片2';
(2)操作 a 标签属性
javascript
// HTML:<a id="link" href="https://www.baidu.com">百度</a>
let link = document.getElementById('link');
// 获取属性
console.log(link.href); // 输出:百度网址
console.log(link.innerText); // 输出:百度
// 设置属性
link.href = 'https://www.google.com';
link.innerText = '谷歌';
3、表单元素的属性操作
表单元素(如 input、button、select 等)有专属属性(如 value、checked、disabled 等),可通过 "元素对象。属性名" 操作:
javascript
// HTML:
// <input type="text" id="input" value="默认值">
// <input type="checkbox" id="checkbox">
// <button id="btn" disabled>按钮</button>
let input = document.getElementById('input');
let checkbox = document.getElementById('checkbox');
let btn = document.getElementById('btn');
// 操作input的value属性
console.log(input.value); // 获取输入框值
input.value = '修改后的输入框值'; // 设置输入框值
// 操作checkbox的checked属性(布尔值)
checkbox.checked = true; // 勾选复选框
// 操作button的disabled属性(布尔值)
btn.disabled = false; // 启用按钮(true为禁用)
4、样式属性操作
操作元素样式有两种方式,分别适用于 "单个样式" 和 "多个样式":
(1)行内样式操作:element.style.样式名
适用于修改单个样式,样式名采用驼峰命名法(如 backgroundColor 而非 background-color):
javascript
// HTML:<div id="box" style="width: 100px;">盒子</div>
let box = document.getElementById('box');
// 设置行内样式
box.style.width = '200px';
box.style.height = '100px';
box.style.backgroundColor = '#ff0000';
box.style.color = 'white';
(2)类样式操作:element.className / element.classList
适用于修改多个样式,推荐使用 classList(更灵活,支持添加、删除、切换类):
javascript
// CSS:
// .active {
// width: 200px;
// height: 100px;
// background-color: #0088ff;
// color: white;
// }
// HTML:<div id="box">盒子</div>
let box = document.getElementById('box');
// 方式1:className(覆盖原有类)
box.className = 'active';
// 方式2:classList(推荐,不覆盖原有类)
box.classList.add('active'); // 添加类
box.classList.remove('active'); // 删除类
box.classList.toggle('active'); // 切换类(有则删,无则加)
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS操作元素</title>
<style>
.active {
width: 200px;
height: 100px;
background-color: #0088ff;
color: white;
text-align: center;
line-height: 100px;
}
</style>
</head>
<body>
<div id="content">原始内容</div>
<img id="pic" src="pic1.jpg" alt="默认图片">
<input type="text" id="txt" value="默认输入值">
<input type="checkbox" id="chk">
<button id="styleBtn">切换样式</button>
<script>
// 1. 修改元素内容
let content = document.getElementById('content');
content.innerHTML = '<h4>修改后的HTML内容</h4>';
// 2. 修改图片属性
let pic = document.getElementById('pic');
pic.src = 'pic2.jpg';
pic.alt = '修改后的图片';
// 3. 操作表单元素
let txt = document.getElementById('txt');
txt.value = '修改后的输入值';
let chk = document.getElementById('chk');
chk.checked = true;
// 4. 切换元素样式
let styleBtn = document.getElementById('styleBtn');
let box = content;
styleBtn.onclick = function() {
box.classList.toggle('active');
};
</script>
</body>
</html>
运行效果如下:


十一、JavaScript BOM
BOM是浏览器提供的一套 API,用于操作浏览器窗口,与 DOM 操作页面结构不同,BOM 操作的是浏览器本身。
1、什么是BOM
BOM 没有统一的标准,但所有浏览器都支持核心的 BOM 对象,核心对象是 window(浏览器窗口),其他 BOM 对象都是 window 的子对象。
2、BOM 的构成
BOM 由多个对象组成,核心对象及作用如下:
- window:浏览器窗口的顶级对象,所有 BOM/DOM 对象都挂载在 window 上,可省略不写;
- document:文档对象(DOM 的核心对象),属于 BOM 的子对象;
- location:地址栏对象,用于操作浏览器的 URL 地址;
- navigator:浏览器对象,用于获取浏览器信息;
- screen:屏幕对象,用于获取用户屏幕信息;
- history:历史记录对象,用于操作浏览器的历史记录。
3、顶级对象 window
window 是 BOM 的顶级对象,有两个核心特点:
- 所有 BOM 子对象(如 location、history)和全局变量、全局函数都挂载在 window 上,访问时可省略 window;
javascript
window.alert('Hello'); // 可简写为 alert('Hello')
window.console.log('Hi'); // 可简写为 console.log('Hi')
- window 有一个特殊的属性 window.self,指向 window 本身。
4、window 对象的常见事件
(1)页面(窗口)加载事件(2 种)
页面加载事件用于在页面完全加载后执行代码,避免因元素未加载完成而无法获取的问题:
- window.onload:页面所有资源(HTML、CSS、图片、JS)加载完成后触发,仅执行一次;
javascript
window.onload = function() {
// 页面加载完成后执行,可安全获取元素
let btn = document.getElementById('btn');
btn.onclick = function() {
alert('页面加载完成后点击按钮');
};
};
- DOMContentLoaded:DOM 结构加载完成后触发(无需等待图片、CSS 加载),执行效率更高,推荐使用;
javascript
document.addEventListener('DOMContentLoaded', function() {
// DOM加载完成后执行
let btn = document.getElementById('btn');
btn.onclick = function() {
alert('DOM加载完成后点击按钮');
};
});
(2)调整窗口大小事件
window.onresize:浏览器窗口大小改变时触发,常用于响应式布局:
javascript
window.onresize = function() {
console.log('窗口大小改变了');
// 获取窗口宽度
let windowWidth = window.innerWidth;
console.log('窗口宽度:', windowWidth);
// 当窗口宽度小于768px时,执行对应逻辑
if (windowWidth < 768) {
console.log('移动端布局');
} else {
console.log('PC端布局');
}
};
代码综合实例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS BOM</title>
</head>
<body>
<button id="btn">点击我</button>
<script>
// 1. 页面加载事件:window.onload
window.onload = function() {
let btn = document.getElementById('btn');
btn.onclick = function() {
// 2. 访问location对象(地址栏)
console.log('当前URL:', window.location.href);
// 跳转到百度
// location.href = 'https://www.baidu.com';
};
};
// 3. DOMContentLoaded事件
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM结构加载完成');
});
// 4. 调整窗口大小事件
window.onresize = function() {
let width = window.innerWidth;
console.log('窗口宽度:', width);
if (width < 480) {
document.body.style.backgroundColor = 'lightblue';
} else if (width < 768) {
document.body.style.backgroundColor = 'lightgreen';
} else {
document.body.style.backgroundColor = 'lightyellow';
}
};
// 5. 访问navigator对象(浏览器信息)
console.log('浏览器信息:', window.navigator.userAgent);
</script>
</body>
</html>
运行效果如下:



十二、JavaScript定时器
定时器是 BOM 的核心功能之一,用于延迟执行或重复执行某段代码,分为 "一次性定时器(setTimeout)" 和 "周期性定时器(setInterval)" 两种。
1、setTimeout () 炸弹定时器
setTimeout() 是一次性定时器,用于延迟指定时间后执行一次代码,执行完毕后定时器自动销毁。
(1)开启定时器
javascript
// 语法:let timerId = setTimeout(回调函数, 延迟时间(毫秒));
// 示例:3秒后弹出提示
let timer1 = setTimeout(function() {
alert('3秒后弹出的提示');
}, 3000); // 3000毫秒 = 3秒
// 简写:使用箭头函数(ES6)
let timer2 = setTimeout(() => {
console.log('5秒后打印的信息');
}, 5000);
(2)案例:5秒后关闭广告
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>5秒后关闭广告</title>
<style>
#ad {
width: 300px;
height: 200px;
background-color: #ffcccc;
text-align: center;
line-height: 200px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div id="ad">广告:5秒后自动关闭</div>
<script>
let ad = document.getElementById('ad');
// 5秒后隐藏广告
setTimeout(() => {
ad.style.display = 'none';
}, 5000);
</script>
</body>
</html>
运行上述代码等待5秒钟之后方框会自动消失。
(3)停止定时器
clearTimeout(timerId) 用于停止未执行的 setTimeout 定时器:
javascript
// 开启定时器
let timer = setTimeout(() => {
alert('定时器执行');
}, 3000);
// 停止定时器(点击按钮停止)
let btn = document.getElementById('btn');
btn.onclick = function() {
clearTimeout(timer);
alert('定时器已停止');
};
2、setInterval () 闹钟定时器
setInterval() 是周期性定时器,用于每隔指定时间重复执行代码,直到手动停止定时器。
(1)开启定时器
javascript
// 语法:let timerId = setInterval(回调函数, 间隔时间(毫秒));
// 示例:每隔1秒打印一次信息
let timer = setInterval(() => {
console.log('每隔1秒打印一次');
}, 1000);
(2)案例:倒计时
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>倒计时案例</title>
<style>
#countdown {
font-size: 24px;
color: red;
text-align: center;
margin-top: 50px;
}
</style>
</head>
<body>
<div id="countdown">10</div>
<script>
let countdown = document.getElementById('countdown');
let num = 10;
// 开启定时器,每隔1秒执行一次
let timer = setInterval(() => {
num--;
countdown.innerText = num;
// 当num为0时,停止定时器
if (num === 0) {
clearInterval(timer);
countdown.innerText = '倒计时结束!';
}
}, 1000);
</script>
</body>
</html>
运行上述代码之后会出现红色的数字10并从数字10开始倒计时,倒计时结束之后会显示倒计时结束!的字样:

(3)停止定时器
clearInterval(timerId) 用于停止 setInterval 定时器:
javascript
// 开启定时器
let timer = setInterval(() => {
console.log('重复执行');
}, 1000);
// 点击按钮停止定时器
let btn = document.getElementById('btn');
btn.onclick = function() {
clearInterval(timer);
console.log('周期性定时器已停止');
};
3、案例:发送短信倒计时
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>发送短信倒计时</title>
</head>
<body>
<button id="sendBtn">发送短信</button>
<script>
let sendBtn = document.getElementById('sendBtn');
sendBtn.onclick = function() {
let time = 60;
// 禁用按钮
sendBtn.disabled = true;
// 开启定时器
let timer = setInterval(() => {
time--;
sendBtn.innerText = `重新发送(${time}s)`;
// 时间到了,恢复按钮
if (time === 0) {
clearInterval(timer);
sendBtn.disabled = false;
sendBtn.innerText = '发送短信';
}
}, 1000);
};
</script>
</body>
</html>
运行上述代码之后会出现一个发送短信的按钮,点击按钮之后会开始从60s倒数,直到倒数结束才会重新显示出来发送短信的按钮:

十三、JavaScript this 指向问题
this 是 JS 中的关键字,指向当前执行代码的 "上下文对象",this 的指向不是固定的,会根据执行环境的不同而变化,新手需掌握 5 种常见场景:
1、全局作用域中 this 指向
全局作用域中,this 指向 window(顶级对象):
javascript
console.log(this); // 输出:window
let num = 10;
console.log(this.num); // 等同于 window.num,输出:10
2、普通函数中 this 指向
普通函数(非箭头函数)中,this 指向函数的 "调用者",若没有明确调用者,指向 window:
javascript
function fn() {
console.log(this);
}
fn(); // 等同于 window.fn(),this指向window
let obj = {
name: '张三',
sayHi: function() {
console.log(this); // this指向obj(函数的调用者)
console.log(this.name); // 输出:张三
}
};
obj.sayHi(); // 调用者是obj
3、事件处理函数中 this 指向
事件处理函数中,this 指向 "事件源"(触发事件的元素):
javascript
// HTML:<button id="btn">点击我</button>
let btn = document.getElementById('btn');
btn.onclick = function() {
console.log(this); // this指向btn(事件源)
this.style.backgroundColor = '#0088ff';
};
4、定时器回调函数中 this 指向
定时器(setTimeout/setInterval)的回调函数中,this 指向 window(默认):
javascript
setTimeout(function() {
console.log(this); // 输出:window
}, 1000);
let obj = {
name: '张三',
fn: function() {
setTimeout(function() {
console.log(this); // 仍指向window,不是obj
console.log(this.name); // 输出:undefined
}, 1000);
}
};
obj.fn();
解决方法:使用箭头函数(箭头函数没有自己的 this,会继承外层作用域的 this):
javascript
let obj = {
name: '张三',
fn: function() {
setTimeout(() => {
console.log(this); // 继承外层fn的this,指向obj
console.log(this.name); // 输出:张三
}, 1000);
}
};
obj.fn();
5、箭头函数中 this 指向
箭头函数没有自己的 this,this 指向箭头函数定义时的 "外层作用域的 this",不会随调用者变化:
javascript
let obj = {
name: '张三
结语
以上便是JavaScript入门的核心脉络。JS的魅力在于灵活的交互实现,入门之路虽有难点,但扎实掌握这些基础,便能从容应对简单项目开发。愿你以本文为起点,多敲代码、多做实践,在动态网页开发的世界里不断探索进阶。