JavaScript 基础教程

本博客系统梳理 JavaScript 核心基础知识,涵盖语法基础、数据类型、流程控制、数组、函数、DOM 操作、事件处理及 BOM 浏览器对象模型等内容。


目录

  1. JavaScript 基本概念
  2. JavaScript 基本语法
  3. 数据类型
  4. 运算符
  5. 流程控制
  6. 数组
  7. 函数
  8. DOM 文档对象模型
  9. 事件
  10. 操作元素
  11. BOM 浏览器对象模型

1. JavaScript 基本概念

1.1 JavaScript 是什么

JavaScript 是一种运行在客户端脚本语言(Script Language),由 Brendan Eich 于 1995 年设计完成,最初命名为 LiveScript,后在与 Sun 合作后更名为 JavaScript。

核心特征:

  • 脚本语言:不需要编译,由 JS 解释器(JS 引擎)逐行解释并执行
  • 弱类型/动态语言:变量类型在运行时自动确定
  • 跨平台:基于 Node.js 技术亦可进行服务器端编程

1.2 JavaScript 的作用

应用领域 说明
表单动态校验 JS 最初的设计目的,如密码强度检测
网页特效 实现页面交互与动画效果
服务端开发 基于 Node.js 构建后端服务
桌面程序 基于 Electron 框架开发
App 开发 基于 Cordova 等混合开发框架
物联网 基于 Ruff 控制硬件
游戏开发 基于 cocos2d-js 等引擎

1.3 HTML / CSS / JS 的关系

三者构成前端开发的三大基石,各司其职:

  • HTML:决定网页结构和内容(相当于人的身体)
  • CSS:决定网页呈现样式(相当于穿衣化妆)
  • JavaScript:实现业务逻辑和页面控制(相当于人的动作)

1.4 JS 的组成

JavaScript 由三个核心部分构成:

JavaScript
├── ECMAScript    → JavaScript 语法标准(核心)
├── DOM           → 页面文档对象模型(Document Object Model)
└── BOM           → 浏览器对象模型(Browser Object Model)

(1) ECMAScript

由 ECMA 国际(原欧洲计算机制造商协会)标准化的编程语言规范,规定了 JS 的编程语法和基础核心知识,是所有浏览器厂商共同遵守的工业标准。

(2) DOM(文档对象模型)

W3C 组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。

(3) BOM(浏览器对象模型)

提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过 BOM 可以操作浏览器窗口,如弹出框、控制浏览器跳转、获取分辨率等。

1.5 JavaScript 的书写方式

(1) 行内式

将单行或少量 JS 代码写在 HTML 标签的事件属性中(以 on 开头的属性):

<input type="button" value="点我试试" onclick="alert('Hello World')"/>

注意:

  • HTML 中推荐使用双引号,JS 中推荐使用单引号
  • 可读性差,大量代码时不方便阅读
  • 引号多层嵌套时容易混淆
  • 仅适用于特殊情况
(2) 内嵌式

将多行 JS 代码写到 <script> 标签中:

<script>
    alert('Hello World~!');
</script>

这是学习阶段最常用的方式。

(3) 外部 JS 文件
<script src="my.js"></script>

优点:

  • 利于 HTML 页面代码结构化
  • 大段 JS 代码独立到 HTML 页面之外,美观且便于文件级别复用
  • 适合于 JS 代码量较大的情况

注意: 引用外部 JS 文件的 <script> 标签中间不可以写代码

1.6 JavaScript 注释

// 单行注释

/*
 * 多行注释
 * 获取用户年龄和姓名
 * 并通过提示框显示出来
 */

2. JavaScript 基本语法

2.1 JavaScript 输入输出语句

方法 说明 归属
alert(msg) 浏览器弹出警示框 浏览器
console.log(msg) 浏览器控制台打印输出信息 浏览器
prompt(info) 浏览器弹出输入框,用户可以输入 浏览器

2.2 变量

通俗理解: 变量是用于存放数据的容器,通过变量名获取数据,数据可以修改。

本质: 变量是程序在内存中申请的一块用来存放数据的空间。

2.3 变量的使用

(1) 变量的声明
var age;  // 声明一个名称为 age 的变量
  • var 是 JS 关键字,用于声明变量(variable 的缩写)
  • 计算机会自动为变量分配内存空间
  • age 是程序员定义的变量名,通过变量名访问内存中分配的空间
(2) 变量的赋值
age = 10;  // 给 age 赋值为 10
  • = 为赋值运算符,将右边的值赋给左边的变量
  • 变量值是程序员保存到变量空间里的值

2.4 变量命名规范

  1. 由字母(A-Z, a-z)、数字(0-9)、下划线(_)、美元符号($)组成
  2. 严格区分大小写var app;var App; 是两个不同的变量
  3. 不能以数字开头18age 是错误的
  4. 不能是关键字或保留字:如 varforwhile
  5. 变量名必须有意义:避免使用无意义的缩写
  6. 遵守驼峰命名法:首字母小写,后面单词的首字母大写,如 myFirstName

3. 数据类型

3.1 数据类型简介

(1) 为什么需要数据类型

在计算机中,不同的数据所需占用的存储空间不同。为了充分利用存储空间,定义了不同的数据类型。简单来说,数据类型就是数据的"类别型号"。

(2) 变量的数据类型

JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定:

var age = 10;        // 数字型
var areYouOk = '是的';  // 字符串型

3.2 数据类型的分类

  • 简单数据类型(基本数据类型):NumberStringBooleanUndefinedNull
  • 复杂数据类型(引用数据类型):Object
(1) 简单数据类型
类型 说明 默认值
Number 数字型,包含整型和浮点型 0
String 字符串型 ""
Boolean 布尔型,truefalse false
Undefined 声明后未赋值的变量 undefined
Null 声明变量并赋值为 null null

数字型 Number:

var age = 21;        // 整数
var Age = 21.3747;   // 小数(浮点数)

字符串型 String:

var strMsg = "我爱北京天安门~";   // 双引号
var strMsg2 = '我爱吃猪蹄~';      // 单引号

布尔型 Boolean:

布尔型和数字型相加时,true 的值为 1false 的值为 0

console.log(true + 1);   // 2
console.log(false + 1);  // 1

Undefined 和 Null:

var variable;
console.log(variable);              // undefined
console.log('你好' + variable);     // "你好undefined"
console.log(11 + variable);          // NaN

var vari = null;
console.log('你好' + vari);        // "你好null"
console.log(11 + vari);             // 11
console.log(true + vari);           // 1

3.3 获取变量数据类型

使用 typeof 运算符获取检测变量的数据类型:

var num = 18;
console.log(typeof num);  // "number"

3.4 数据类型转换

通常实现三种方式的转换:

  • 转换为字符串类型
  • 转换为数字型
  • 转换为布尔型
(1) 转换为字符串
方式 说明 案例
toString() 转成字符串 var num = 1; alert(num.toString());
String() 强制转换 转成字符串 var num = 1; alert(String(num));
加号拼接字符串 和字符串拼接的结果都是字符串 var num = 1; alert(num + "我是字符串");
(2) 转换为数字型(重点)
方式 说明 案例
parseInt(string) 将 string 类型转成整数数值型 parseInt('78')
parseFloat(string) 将 string 类型转成浮点数数值型 parseFloat('78.21')
Number() 强制转换 将 string 类型转换为数值型 Number('12')
利用算术运算 - * / 隐式转换 '12' - 0
(3) 转换为布尔型

使用 Boolean() 函数:

  • 代表空、否定的值会被转换为 false''(空字符串)、0NaNnullundefined
  • 其余值都会被转换为 true

4. 运算符

运算符(operator)是用于实现赋值、比较和执行算术运算等功能的符号。

4.1 算术运算符

运算符 描述 实例
+ 10 + 20 = 30
- 10 - 20 = -10
* 10 * 20 = 200
/ 10 / 20 = 0.5
% 取余数(取模) 9 % 2 = 1

4.2 递增和递减运算符

(1) 前置递增运算符 ++num

先自加 1,后返回值:

var num = 10;
alert(++num + 10);  // 21(num 先变为 11,再加 10)
(2) 后置递增运算符 num++

先返回原值,后自加:

var num = 10;
alert(10 + num++);  // 20(先返回 10,num 后变为 11)

4.3 比较运算符

比较运算符用于两个数据的比较,返回布尔值 truefalse

运算符 说明 案例 结果
> 大于号 1 > 2 false
< 小于号 1 < 2 true
>= 大于等于号 2 >= 2 true
<= 小于等于号 2 <= 2 true
== 判等号(会转型) 37 == 37 true
!= 不等号 37 != 37 false
=== 全等号(要求值和数据类型都一致) 37 === '37' false
!== 不全等号 37 !== '37' true

4.4 逻辑运算符

用于布尔值运算,返回值也是布尔值。

运算符 说明 案例
&& 逻辑与,两边都为 true 才返回 true 2 > 1 && 3 > 1true
|| 逻辑或,两边都为 false 才返回 false 2 > 3 || 1 < 2true
! 逻辑非,取反 !truefalse

4.5 赋值运算符

运算符 说明 案例
= 直接赋值 var age = 10;
+=-= 加、减一个数后再赋值 age += 5;(相当于 age = age + 5
*=/=%= 乘、除、取模后再赋值 age *= 10;(相当于 age = age * 10

4.6 运算符优先级

优先级 运算符 顺序
1 小括号 ()
2 一元运算符 ++--!
3 算术运算符 * / %,后 + -
4 关系运算符 > >= < <=
5 相等运算符 == != === !==
6 逻辑运算符 &&||
7 赋值运算符 =
8 逗号运算符 ,

5. 流程控制

流程控制用于控制代码按照一定结构顺序执行,主要有三种结构:

  • 顺序结构:按代码书写顺序依次执行
  • 分支结构:根据条件判断执行不同路径
  • 循环结构:重复执行某段代码

5.1 if 分支流程控制

(1) if 语句
if (条件表达式) {
    // 条件成立时执行的代码语句
}

执行流程:判断条件 → 条件为 true → 执行语句 → 继续执行后续代码;条件为 false → 跳过执行语句 → 继续执行后续代码。

(2) if else if 语句(多分支)
if (条件表达式1) {
    语句1;
} else if (条件表达式2) {
    语句2;
} else if (条件表达式3) {
    语句3;
} else {
    // 上述条件都不成立时执行
}
(3) 三元表达式
表达式1 ? 表达式2 : 表达式3;
  • 如果表达式 1 为 true,返回表达式 2 的值
  • 如果表达式 1 为 false,返回表达式 3 的值
  • 相当于 if else 双分支的简写形式

5.2 switch 分支流程控制

switch(表达式) {
    case value1:
        // 表达式等于 value1 时执行的代码
        break;
    case value2:
        // 表达式等于 value2 时执行的代码
        break;
    default:
        // 表达式不等于任何一个 value 时执行的代码
}

注意:

  • switch 后面的表达式通常是一个变量
  • case 后跟选项的值,后面跟冒号
  • 如果存在匹配全等(===),执行对应代码块,遇到 break 时停止
  • 如果没有 break,会继续执行下一个 case 里面的语句(穿透现象)

5.3 for 循环

for (初始化变量; 条件表达式; 操作表达式) {
    // 循环体
}

执行过程:

  1. 执行初始化变量(仅执行一次)
  2. 执行条件表达式,若为 true 则执行循环体,否则退出循环
  3. 执行操作表达式,第一轮结束
  4. 第二轮开始,直接执行条件表达式(不再初始化),重复步骤 2-3
  5. 直至条件表达式为 false,结束整个循环

5.4 while 循环

while (条件表达式) {
    // 循环体代码
}

执行思路:

  1. 先执行条件表达式,结果为 true 则执行循环体,为 false 则退出循环
  2. 执行循环体代码
  3. 循环体执行完毕后,继续判断条件表达式
  4. 必须有退出条件,否则会成为死循环

5.5 do-while 循环

do {
    // 循环体代码
} while (条件表达式);

特点: 先执行一次循环体,再判断条件。因此 do...while 循环至少会执行一次循环体代码。

5.6 continue 和 break

关键字 作用
continue 立即跳出本次循环,继续下一次循环(本次循环体中 continue 之后的代码少执行一次)
break 立即跳出整个循环,循环结束

6. 数组

6.1 数组的概念

数组是指一组数据的集合,其中的每个数据被称作元素。数组可以把一组相关的数据一起存放,并提供方便的访问方式。数组是一种将一组数据存储在单个变量名下的优雅方式,数组中可以存放任意类型的元素。

6.2 创建数组

方式一:利用 new 创建数组
var arr = new Array();  // 创建一个新的空数组

注意: Array() 中的 A 要大写。

方式二:利用数组字面量创建数组(推荐)
// 创建空数组
var arr = [];

// 创建带初始值的数组
var arr = ['小白', '小黑', '大黄', '瑞奇'];

数组的字面量是方括号 [],声明数组并赋值称为数组的初始化。

6.3 获取数组中的元素

索引(下标):用来访问数组元素的序号,数组下标从 0 开始

var arr = ['小白', '小黑', '大黄', '瑞奇'];
// 索引号:  0      1      2      3

console.log(arr[1]);  // "小黑"

注意: 如果访问时数组没有和索引值对应的元素,则得到的值是 undefined

6.4 遍历数组

把数组中的每个元素从头到尾都访问一次,通常通过 for 循环索引遍历:

var arr = ['red', 'green', 'blue'];
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

数组的长度: 使用 数组名.length 可以访问数组元素的数量(数组长度)。

var arr = [1, 2, 3];
console.log(arr.length);  // 3

注意:

  • 数组的长度是数组元素的个数,不要和数组的索引号混淆
  • 数组元素个数变化时,length 属性会同步变化
  • 可以修改 length 属性:大于元素个数会在末尾出现空白元素;小于元素个数会删除超出部分

6.5 数组中新增元素

在数组末尾插入新元素:

数组[数组.length] = 新数据;

7. 函数

7.1 函数的概念

函数是封装了一段可被重复调用执行的代码块。通过函数可以实现大量代码的重复使用。

7.2 函数的使用

(1) 声明函数
function 函数名() {
    // 函数体代码
}
  • function 是声明函数的关键字,必须小写
  • 函数名通常命名为动词,如 getSum
(2) 调用函数
函数名();  // 通过调用函数名来执行函数体代码

口诀:函数不调用,自己不执行。 声明函数本身不会执行代码,只有调用时才会执行。

7.3 函数的封装

函数的封装是把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。简单理解:封装类似于将电脑配件整合组装到机箱中。

7.4 函数的参数

(1) 函数参数语法
  • 形参:函数定义时设置接收调用时传入的参数
  • 实参:函数调用时传入小括号内的真实数据
// 带参数的函数声明
function 函数名(形参1, 形参2, 形参3...) {
    // 函数体
}

// 带参数的函数调用
函数名(实参1, 实参2, 实参3...);

注意:

  1. 调用时实参值传递给形参
  2. 形参简单理解为:不用声明的变量
  3. 实参和形参的多个参数之间用逗号 , 分隔
(2) 形参和实参数量不匹配时
情况 说明
实参个数等于形参个数 正常输出结果
实参个数多于形参个数 只取到形参的个数
实参个数少于形参个数 多余的形参定义为 undefined,最终结果为 NaN

注意: 在 JavaScript 中,形参的默认值是 undefined

7.5 函数的返回值

(1) return 语句
function 函数名() {
    return 需要返回的值;
}

函数名();  // 调用函数可以得到 return 后面的值
  • 在使用 return 语句时,函数会停止执行,并返回指定的值
  • 如果函数没有 return,返回的值是 undefined
(2) break、continue、return 的区别
关键字 作用
break 结束当前的循环体(如 forwhile
continue 跳出本次循环,继续执行下次循环
return 不仅可以退出循环,还能返回 return 语句中的值,同时结束当前函数体内的代码

7.6 arguments 的使用

当不确定有多少个参数传递时,可以用 arguments 来获取。arguments 是当前函数的一个内置对象,所有函数都内置了 arguments 对象,它存储了传递的所有实参。

arguments 展示形式是一个伪数组,具有以下特点:

  • 具有 length 属性
  • 按索引方式储存数据
  • 不具有数组的 pushpop 等方法

7.7 函数的两种声明方式

方式一:自定义函数方式(命名函数)
function fn() {
    // ...
}
fn();

因为有名字,所以也被称为命名函数。调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面。

方式二:函数表达式方式(匿名函数)
var fn = function() {
    // ...
};
fn();  // 函数调用必须写到函数体下面
  • 函数没有名字,所以也被称为匿名函数
  • fn 里面存储的是一个函数
  • 函数调用的代码必须写到函数体后面

7.8 作用域

(1) 作用域概述

作用域是指限定名字可用性的代码范围。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

JavaScript(ES6 之前)中的作用域有两种:

  • 全局作用域
  • 局部作用域(函数作用域)
(2) 全局作用域

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

(3) 局部作用域

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

(4) JS 没有块级作用域(ES6 之前)

在其他编程语言(如 Java、C#)中,if 语句、循环语句中创建的变量只能在本语句中使用。但 JavaScript 在 ES6 之前没有块级作用域:

if (true) {
    var num = 123;
    console.log(123);  // 123
}
console.log(123);  // 123(在 if 外面也能访问)
(5) 变量的作用域
类型 定义 特点
全局变量 在全局作用域下声明的变量(函数外部定义) 任何地方都可以使用,浏览器关闭时才销毁,比较占内存
局部变量 在局部作用域下声明的变量(函数内部定义) 只在函数内部使用,代码块执行结束后销毁,节省内存

特殊情况: 在函数内不使用 var 声明的变量也是全局变量(不建议使用)。


8. DOM 文档对象模型

8.1 什么是 DOM

文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML 或 XHTML)的标准编程接口。

W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。DOM 是 W3C 组织制定的一套处理 HTML 和 XML 文档的规范,所有浏览器都遵循了这套标准。

8.2 DOM 树

DOM 树又称为文档树模型,把文档映射成树形结构,通过节点对象对其处理。

  • 文档:一个页面就是一个文档,DOM 中使用 document 表示
  • 节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用 node 表示
  • 元素节点:网页中的所有标签,通常称为元素节点,简称为"元素",使用 element 表示

8.3 获取元素

DOM 把以上内容都看做是对象。要操作页面上的某部分(显示/隐藏、动画),需要先获取到该部分对应的元素。

(1) 根据 ID 获取
document.getElementById(id)
  • 作用:根据 ID 获取元素对象
  • 参数:id 值,区分大小写的字符串
  • 返回值:元素对象或 null
var timer = document.getElementById('time');
console.log(timer);
console.log(typeof timer);  // "object"
console.dir(timer);         // 打印元素对象的属性和方法
(2) 根据标签名获取元素
document.getElementsByTagName('标签名')
// 或
element.getElementsByTagName('标签名')
  • 作用:根据标签名获取元素对象
  • 参数:标签名
  • 返回值:元素对象集合(伪数组,数组元素是元素对象)

注意: getElementsByTagName() 获取到的是动态集合,当页面增加了标签,这个集合中也就增加了元素。

(3) H5 新增获取元素方式
// 根据类名返回元素对象集合
document.getElementsByClassName('类名');

// 根据指定选择器返回第一个元素对象
document.querySelector('选择器');

// 根据指定选择器返回所有元素对象集合
document.querySelectorAll('选择器');

注意: querySelectorquerySelectorAll 里面的选择器需要加符号,如 .box(类选择器)、#nav(id 选择器)。

(4) 获取特殊元素(body、html)
// 获取 body 元素
document.body;

// 获取 html 元素
document.documentElement;

9. 事件

9.1 事件概述

JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。简单理解:触发-响应机制

网页中的每个元素都可以产生某些可以触发 JavaScript 的事件,例如用户点击某按钮时产生一个事件,然后去执行某些操作。

9.2 事件三要素

要素 说明 示例
事件源 触发事件的元素(谁) 按钮
事件类型 如何触发,什么事件(什么) 鼠标点击 onclick
事件处理程序 事件触发后要执行的代码(做啥) 函数形式的事件处理函数
var btn = document.getElementById('btn');  // 事件源
btn.onclick = function() {                  // 事件类型 + 事件处理程序
    alert('点秋香');
};

9.3 执行事件的步骤

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值形式)

9.4 常见的鼠标事件

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

10. 操作元素

JavaScript 的 DOM 操作可以改变网页内容、结构和样式,通过元素对象的属性实现。

10.1 改变元素内容(获取或设置)

属性 说明
element.innerText 从起始位置到终止位置的文本内容,去除 HTML 标签,同时去掉空格和换行
element.innerHTML 起始位置到终止位置的全部内容,包括 HTML 标签,同时保留空格和换行

获取内容时的区别: innerText 会去除空格和换行,而 innerHTML 会保留空格和换行。

设置内容时的区别: innerText 不会识别 HTML 标签,而 innerHTML 会识别。

// innerText 不识别 HTML 标签
div.innerText = '<strong>今天是:</strong>2019';  // 原样输出字符串

// innerHTML 识别 HTML 标签(W3C 标准)
div.innerHTML = '<strong>今天是:</strong>2019';   // "今天是:" 加粗显示

10.2 常用元素的属性操作

操作 语法
获取属性值 元素对象.属性名
设置属性值 元素对象.属性名 = 值

常用属性:innerTextinnerHTMLsrchrefidalttitle

10.3 表单元素的属性操作

表单元素中有一些属性如 disabledcheckedselected,元素对象的这些属性的值是布尔型

// 获取属性值
元素对象.属性名;

// 设置属性值
元素对象.属性名 =;

10.4 样式属性操作

方式一:通过操作 style 属性(行内样式操作)
元素对象.style.样式属性 =;

注意:

  1. JS 里面的样式采取驼峰命名法,如 backgroundColor
  2. JS 修改 style 样式操作产生的是行内样式,权重比较高
方式二:通过操作 className 属性(类名样式操作)
元素对象.className =;

注意:

  • class 是关键字,所以使用 className
  • className 会直接覆盖原先的类名
  • 若要保留原有类名,可采用多类名选择器的方式:元素对象.className = '原类名 新类名'

11. BOM 浏览器对象模型

11.1 什么是 BOM

BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window

BOM 由一系列相关的对象构成,每个对象都提供了很多方法与属性。BOM 缺乏统一标准,最初是 Netscape 浏览器标准的一部分。

11.2 BOM 的构成

window(BOM 的顶级对象)
├── document    → DOM 的顶级对象
├── location    → 地址栏相关
├── navigation  → 浏览器信息
├── screen      → 屏幕信息
└── history     → 历史记录

BOM 比 DOM 更大,它包含 DOM。

11.3 顶级对象 window

window 对象是浏览器的顶级对象,具有双重角色:

  1. 它是 JS 访问浏览器窗口的一个接口
  2. 它是一个全局对象,定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法

注意: 在调用的时候可以省略 window,如 alert()prompt() 等。

11.4 window 对象的常见事件

(1) 页面(窗口)加载事件

第 1 种:window.onload

window.onload = function() {
    // 页面内容完全加载完成后执行
};

// 或使用 addEventListener
window.addEventListener('load', function() {
    // ...
});
  • window.onload 是窗口(页面)加载事件,当文档内容完全加载完成后触发(包括图像、脚本文件、CSS 文件等)
  • 有了 window.onload 就可以把 JS 代码写到页面元素的上方
  • window.onload 传统注册事件方式只能写一次,以最后一个为准
  • 使用 addEventListener 则没有限制

第 2 种:DOMContentLoaded

document.addEventListener('DOMContentLoaded', function() {
    // DOM 加载完成后执行(不包括样式表、图片、flash 等)
});
  • DOMContentLoaded 事件触发时,仅当 DOM 加载完成
  • IE9 以上才支持
  • 如果页面图片很多,使用此事件更合适,可以更快实现交互效果
(2) 调整窗口大小事件
window.onresize = function() {
    // 窗口大小发生变化时执行
};

// 或使用 addEventListener
window.addEventListener('resize', function() {
    // ...
});

注意:

  1. 只要窗口大小发生像素变化,就会触发这个事件
  2. 经常利用这个事件完成响应式布局
  3. window.innerWidth 可获取当前屏幕宽度

11.5 定时器

window 对象提供了两个定时器方法:

(1) setTimeout() —— 炸弹定时器(一次性)
window.setTimeout(调用函数, [延迟的毫秒数]);
  • 在指定的延迟时间后执行一次调用函数
  • 延迟的毫秒数省略默认为 0
  • 这个调用函数也称为回调函数(callback)

停止定时器:

clearTimeout(timeoutID);
(2) setInterval() —— 闹钟定时器(重复性)
window.setInterval(回调函数, [间隔的毫秒数]);
  • 每隔指定的间隔时间重复执行回调函数
  • 第一次执行也是间隔毫秒数之后

停止定时器:

clearInterval(intervalID);

回调函数的理解:

普通函数是按照代码顺序直接调用,而回调函数是回头调用的意思——上一件事干完,再回头调用这个函数。定时器中的调用函数、事件处理函数都是回调函数。

11.6 this 指向问题

this 的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定。一般情况下,this 最终指向的是那个调用它的对象

现阶段 this 指向总结:

场景 this 指向
全局作用域或普通函数中 全局对象 window(定时器里面的 this 也指向 window
方法调用中 谁调用,this 指向谁
构造函数中 this 指向构造函数的实例
// 1. 全局作用域中 this 指向 window
console.log(this);

// 2. 普通函数中 this 指向 window
function fn() {
    console.log(this);
}
window.fn();

// 3. 定时器中 this 指向 window
window.setTimeout(function() {
    console.log(this);
}, 1000);

// 4. 方法调用中,this 指向调用它的对象
var o = {
    sayHi: function() {
        console.log(this);  // this 指向 o 对象
    }
};
o.sayHi();

// 5. 事件处理函数中,this 指向触发事件的元素对象
btn.addEventListener('click', function() {
    console.log(this);  // this 指向 btn 按钮对象
});

// 6. 构造函数中,this 指向实例对象
function Fun() {
    console.log(this);  // this 指向 fun 实例对象
}
var fun = new Fun();

附录:学习要点总结

章节 核心掌握内容
JS 基础概念 脚本语言特征、JS 组成(ECMAScript + DOM + BOM)、三种书写方式
基本语法 输入输出语句、变量声明与赋值、命名规范
数据类型 五种简单类型、typeof 检测、三种类型转换方式
运算符 算术/递增/比较/逻辑/赋值运算符,运算符优先级
流程控制 if/switch 分支,for/while/do-while 循环,continue/break
数组 两种创建方式、索引访问、遍历、length 属性、新增元素
函数 声明与调用、参数传递、return 返回值、arguments、两种声明方式、作用域
DOM DOM 树概念、四种获取元素方式、特殊元素获取
事件 事件三要素、执行步骤、常见鼠标事件
操作元素 innerText/innerHTML 区别、属性操作、style/className 样式操作
BOM window 对象、页面加载事件、调整窗口大小事件、两种定时器、this 指向

更多推荐