Skip to content

JavaScript 编程基础 ​

前置知识:HTML + CSS 基础 课程定位:前端编程入门,为后续 Node.js、Vue、大数据可视化打基础


目录 ​


第一章 初识JavaScript ​

1.1 什么是JavaScript ​

JavaScript 是一种基于对象和事件驱动的客户端脚本语言,主要用于开发交互式网页。

主要应用领域:

  • 表单动态校验
  • 网页特效与动画
  • 前端开发(Web + APP + 小程序)
  • 服务端开发(Node.js)
  • 桌面程序(Electron)
  • 移动App(Cordova)
  • 物联网(Ruff)
  • 游戏开发(cocos2d-js)
  • 数据库操作(MongoDB)

1.2 网页三要素与浏览器内核 ​

网页三大组成部分:

  • HTML:页面结构与内容
  • CSS:页面样式与布局
  • JavaScript:页面交互与行为

浏览器内核组成:

  • 渲染引擎(排版引擎):解析 HTML 与 CSS,如 Chrome 的 Blink
  • JS引擎:JavaScript 解释器,如 Chrome 的 V8 引擎

💡 JS代码执行特点:逐行解释执行,不需要预先编译。


1.3 JavaScript的特点 ​

特点说明
解释性脚本语言不需要编译,逐行解释执行(对比:Java、C++是编译语言)
跨平台不依赖操作系统,只要有浏览器支持即可运行
支持面向对象基于对象的编程,也支持函数式编程
弱类型变量不需要声明类型,赋值时自动确定类型
简单性语法相对简单,入门门槛低

1.4 JavaScript的组成 ​

JavaScript 由三大部分组成:

JavaScript
├── ECMAScript(核心语法)   —— 基本语法、数据类型、流程控制、函数、对象等
├── DOM(文档对象模型)       —— 操作网页元素的接口
└── BOM(浏览器对象模型)     —— 操作浏览器窗口的接口

常用JS框架: React.js、Angular.js、Vue.js(尤雨溪)


1.5 常用开发工具 ​

  • VS Code(推荐):微软出品,轻量强大,插件丰富
  • HBuilder:国产,前端开发友好
  • Sublime Text:轻量快速
  • DreamWeaver:可视化编辑
  • WebStorm:JetBrains出品,功能强大

VS Code 推荐插件:

  • Chinese (Simplified) —— 中文语言包
  • Open in Browser —— 浏览器打开

1.6 JS代码的三种书写位置 ​

(1)行内式 ​

写在 HTML 标签的事件属性中(如 onclick、oninput、onmousemove)

html
<input type="button" value="提交" onclick="alert('你提交成功!')" />
<input type="text" onmousemove="console.log('鼠标移动了')" />

(2)内嵌式(嵌入式) ​

将 JS 代码写在 <script> 标签中,放在 <head> 或 <body> 里

html
<script>
    var a = 11;
    var b = 22;
    var c = a + b;
    console.log(c);
</script>

(3)外部式(外链式) ​

将 JS 代码写在单独的 .js 文件中,通过 script 标签引入

html
<script src="js/test.js"></script>

⚠️ 注意:引入外部JS的script标签中间不能再写代码。


1.7 语法规则与注释 ​

语法规则:

  1. JS 严格区分大小写
  2. 对空格、换行、缩进不敏感
  3. 每行结束的分号 ; 可以省略,但推荐加上

注释:

javascript
// 单行注释,快捷键:ctrl + /

/* 
   多行注释
   快捷键:ctrl + shift + /
*/

1.8 输入输出语句 ​

语句作用示例
alert('信息')弹出警告框alert('这是警告框')
console.log('信息')控制台输出(调试用)console.log('调试信息')
prompt('提示信息')弹出输入框,返回用户输入var age = prompt('请输入年龄')

控制台使用: 按 F12 打开开发者工具 → Console(控制台)面板


1.9 变量 ​

变量是内存中的一块空间,用于存储数据。

声明与赋值 ​

javascript
// 声明变量
var age;

// 赋值
age = 18;

// 声明同时赋值(推荐)
var age = 18;

⚠️ 可以不声明直接赋值,但不规范,不推荐。

变量命名规范 ​

  1. 由**字母、数字、下划线、美元符号$**组成
  2. 严格区分大小写
  3. 不能以数字开头
  4. 不能是关键字、保留字
    • 关键字:JS中已经被使用的单词(如 break、if、for 等)
    • 保留字:未来可能成为关键字的单词
  5. 合理命名,"见其名知其意"
  6. 三种命名法:
javascript
// 小驼峰命名法(推荐,变量/函数用)
var mySchoolAddress = '重庆涪陵';

// 大驼峰命名法(类名/构造函数用)
var MySchoolAddress = '重庆涪陵';

// 下划线命名法
var my_school_address = '重庆涪陵';

第二章 JS基础语法 ​

2.1 数据类型 ​

JS 是弱类型语言,变量不需要提前声明数据类型。

数据类型分类:

数据类型
├── 基本数据类型(值类型)
│   ├── Number    数值型
│   ├── String    字符串型
│   ├── Boolean   布尔型
│   ├── Null      空型
│   └── Undefined 未定义型
└── 引用数据类型(复杂类型)
    └── Object    对象

(1)Number 数值型 ​

包括整数、浮点数(小数)、NaN、Infinity

javascript
// 整数
var age = 18;

// 浮点数
var price = 99.99;

// 最大值/最小值
var max = Number.MAX_VALUE;
var min = Number.MIN_VALUE;

// 无穷大/无穷小
var inf = Infinity;
var ninf = -Infinity;

// NaN:非数值(Not a Number)
// isNaN():判断是否为非数字,true=非数字,false=数字
console.log(isNaN('abcdefg'));  // true

(2)String 字符串型 ​

用单引号 '' 或双引号 "" 包裹。

javascript
var str1 = '这是一个字符串';
var str2 = "这也是一个字符串";

转义字符:

转义符含义
\n换行
\'单引号
\"双引号
\\反斜杠

字符串长度: length 属性

javascript
var str = 'hello world';
console.log(str.length);  // 11

访问字符串字符: 通过索引 [index],索引从0开始,超出返回 undefined

javascript
var str = '这是一个字符串';
console.log(str[0]);      // '这'
console.log(str[100]);    // undefined

字符串拼接: 使用 + 号

javascript
var first = '520';
var second = '10';
var result = first + second;  // '52010'

(3)Boolean 布尔型 ​

只有两个值:true(真)和 false(假)

(4)Null 空型 ​

表示空值,专门用来表示一个空对象引用。

javascript
var a = null;
if (a === null) {
    alert('这是null型');
}

(5)Undefined 未定义型 ​

声明了变量但没有赋值,默认值就是 undefined。

javascript
var test;   // 声明但未赋值
alert(test); // undefined

检测数据类型:typeof ​

javascript
var result = true;
console.log(typeof result);  // 'boolean'

2.2 数据类型转换 ​

(1)转换为字符串类型 ​

方法说明示例
+ ""拼接字符串(最常用)var str = num + ""
toString()转字符串var str = num.toString()
String()强制转换var str = String(num)
javascript
var num = 123;
var str1 = num + '';           // '123'
var str2 = num.toString();     // '123'
var str3 = String(num);        // '123'

(2)转换为数字类型 ​

方法说明示例
parseInt()转整数parseInt('123.99') → 123
parseFloat()转浮点数parseFloat('123.99') → 123.99
Number()强制转换Number('123') → 123
算术隐式转换- * / 运算时自动转'12' - 1 → 11
javascript
var str = '111.000';
parseInt(str);     // 111
parseFloat(str);   // 111

(3)转换为布尔型 ​

Boolean() 函数转换,以下值会转为 false,其余都转 true:

  • 0
  • ''(空字符串)
  • null
  • undefined
  • NaN

2.3 运算符 ​

(1)算术运算符 ​

+  加    -  减    *  乘    /  除    %  取模(取余数)

(2)递增递减运算符 ​

++ 自增,-- 自减

javascript
var i = 10;
i++;   // 等同于 i = i + 1
i--;   // 等同于 i = i - 1

前置与后置的区别:

  • x++:返回计算前的值,然后再加1
  • ++x:先加1,然后返回计算后的值
javascript
var a = 10;
console.log(a++);  // 10(先返回后加)
console.log(a);    // 11

var b = 10;
console.log(++b);  // 11(先加后返回)

(3)比较运算符 ​

结果为布尔值(true/false)

>   大于    <   小于    >=  大于等于   <=  小于等于
==  等于(只比较值,自动类型转换)
!=  不等于
=== 全等(值和类型都相等才为true)
!== 不全等
javascript
console.log('' == 0);    // true(自动类型转换)
console.log('' === 0);   // false(类型不同)

💡 推荐使用 === 和 !==,更严谨。

(4)逻辑运算符 ​

结果为布尔值

运算符含义规则
&&与(和)两边都为true,结果才为true
||或有一边为true,结果就为true
!非(取反)true变false,false变true

(5)赋值运算符 ​

=   赋值
+=  x += y  等同于  x = x + y
-=  x -= y  等同于  x = x - y
*=  x *= y  等同于  x = x * y
/=  x /= y  等同于  x = x / y
%=  x %= y  等同于  x = x % y

(6)三元运算符 ​

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

条件为true执行表达式1,为false执行表达式2。

javascript
var score = 85;
var result = score >= 60 ? '及格' : '不及格';

(7)运算符优先级 ​

从高到低: 小括号 > 算术运算符 > 比较运算符 > 逻辑运算符 > 赋值运算符


2.4 流程控制 ​

三种基本结构:顺序结构、分支结构、循环结构

(1)顺序结构 ​

默认执行方式,代码从上到下逐行执行。

(2)分支结构 ​

单分支 if:

javascript
if (条件表达式) {
    // 条件为true时执行
}

双分支 if...else:

javascript
if (条件表达式) {
    // 条件为true时执行
} else {
    // 条件为false时执行
}

多分支 if...else if...else:

javascript
if (条件1) {
    // 条件1为true
} else if (条件2) {
    // 条件2为true
} else if (条件3) {
    // 条件3为true
} else {
    // 都不满足
}

switch 语句:

javascript
switch (表达式) {
    case 值1:
        // 代码段1
        break;
    case 值2:
        // 代码段2
        break;
    default:
        // 都不匹配时执行
}

⚠️ 注意:break 不能少,否则会发生 case 穿透。

(3)循环结构 ​

for 循环: 适合循环次数已知的情况

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

// 示例:打印1~100
for (var i = 1; i <= 100; i++) {
    console.log(i);
}

while 循环: 先判断条件再执行,适合次数未知

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

do...while 循环: 无条件先执行一次,再判断条件

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

(4)continue 与 break ​

  • continue:跳过本次循环,继续下一次
  • break:终止整个循环
javascript
// 多层循环时,默认只跳过/终止最近一层
// 如需操作外层循环,需要加标签
outer: for (var i = 0; i < 5; i++) {
    for (var j = 0; j < 5; j++) {
        if (j === 2) {
            continue outer;  // 跳过外层循环的本次
        }
    }
}

2.5 数组 ​

数组是值的有序集合。

特点:

  • JS是弱类型,同一数组可存放多种类型元素
  • 长度可动态调整

创建数组 ​

javascript
// 方式1:字面量(推荐)
var arr1 = [];
var color = ['red', 'green', 'blue', 1, true, null];

// 方式2:new Array()
var arr2 = new Array();

访问数组元素 ​

通过数字索引访问,索引从0开始

javascript
var color = ['red', 'green', 'blue'];
console.log(color[0]);  // 'red'
console.log(color[2]);  // 'blue'

数组长度 ​

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

遍历数组 ​

javascript
// 方式1:for循环(最常用)
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}

// 方式2:for...in
for (var index in arr) {
    console.log(arr[index]);
}

// 方式3:for...of(ES6)
for (var item of arr) {
    console.log(item);
}

修改数组 ​

javascript
// 修改长度
arr.length = 10;

// 新增/修改元素(通过索引)
arr[0] = '新值';
arr[100] = '末尾新增';  // 中间会有空位

二维数组 ​

javascript
// 创建
var arr2d = [[1, 2], [3, 4], [5, 6]];

// 访问
console.log(arr2d[0][1]);  // 2

// 遍历:双层for循环
for (var i = 0; i < arr2d.length; i++) {
    for (var j = 0; j < arr2d[i].length; j++) {
        console.log(arr2d[i][j]);
    }
}

2.6 函数 ​

函数就是一段可重复使用的代码块,实现代码复用。

函数的声明与调用 ​

javascript
// 声明函数
function 函数名(参数1, 参数2, ...) {
    // 函数体
    return 返回值;
}

// 调用函数
函数名(参数1, 参数2, ...);
javascript
// 示例
function sayHi() {
    console.log('hi');
}
sayHi();

函数参数 ​

  • 形参:函数声明时的参数(占位符)
  • 实参:函数调用时传入的参数(实际值)
javascript
// 形参:num1, num2
function getSum(num1, num2) {
    var sum = 0;
    for (var i = num1; i <= num2; i++) {
        sum += i;
    }
    return sum;
}

// 实参:1, 100
getSum(1, 100);

参数数量不匹配:

  • 形参 < 实参:多余的实参会被忽略
  • 形参 > 实参:多余的形参值为 undefined

返回值 return ​

javascript
function add(a, b) {
    return a + b;  // 终止函数并返回结果
}

💡 如果函数没有指定 return,默认返回 undefined return 可以提前终止函数执行

arguments 对象 ​

接收所有实参,是一个伪数组(类数组对象)

javascript
function sum() {
    var total = 0;
    for (var i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}
sum(1, 2, 3, 4, 5);  // 15

匿名函数 ​

没有函数名的函数

javascript
// 立即执行函数(IIFE)
(function (a, b) {
    console.log(a + b);
})(1, 2);

函数表达式 ​

将匿名函数赋值给变量,通过变量调用

javascript
var sayHi = function () {
    console.log('hello world');
};

sayHi();  // 调用

⚠️ 函数表达式必须写在调用之前。

回调函数 ​

将函数作为参数传递给另一个函数

javascript
function calc(num1, num2, fn) {
    return fn(num1, num2);
}

// 使用
calc(10, 20, function (a, b) {
    return a + b;
});

递归 ​

函数自己调用自己

javascript
// 计算阶乘
function factorial(n) {
    if (n === 1) return 1;
    return n * factorial(n - 1);
}

2.7 作用域与闭包 ​

作用域 ​

变量可访问的范围。

全局变量:

  • 不在函数内声明的变量,或函数内省略 var 声明的变量
  • 在整个页面生效
  • 页面关闭时才销毁,比较占内存

局部变量:

  • 函数内用 var 声明的变量
  • 只能在当前函数内使用
  • 函数执行完就销毁,节省内存

块级变量(ES6 let):

  • 用 let 声明,仅在 {} 内有效(if、for、while 等)

作用域链 ​

由内向外查找变量: 当前函数内查找 → 上一级函数查找 → ... → 全局作用域

函数内部可以访问外部的变量,但外部不能访问函数内部的变量。

闭包 ​

有权访问另一个函数作用域内变量的函数。

两个作用:

  1. 函数外部读取函数内部的变量
  2. 让变量常驻内存(不会被垃圾回收)
javascript
function outer() {
    var count = 0;
    return function () {
        count++;
        return count;
    };
}

var counter = outer();
counter();  // 1
counter();  // 2

第三章 对象编程 ​

3.1 对象概述 ​

面向对象编程(OOP):万物皆对象。

对象是一种数据类型,由属性和方法组成:

  • 属性:事物的特征,通过 对象.属性 访问
  • 方法:事物的行为,通过 对象.方法名() 访问

3.2 创建自定义对象的三种方式 ​

方式1:字面量创建(最常用) ​

javascript
var car = {
    color: 'red',
    brand: 'BMW',
    price: 300000,
    run: function () {
        console.log('车在跑');
    }
};

特点:

  • 用大括号 {} 包裹
  • 每个成员是键值对 key: value
  • 成员之间用逗号分隔

方式2:new Object() 创建 ​

javascript
var car = new Object();
car.color = 'red';
car.brand = 'BMW';
car.run = function () {
    console.log('车在跑');
};

方式3:构造函数创建(批量创建对象) ​

构造函数名首字母大写,使用 this 指代当前对象。

javascript
// 构造函数(模板)
function Car(color, brand) {
    this.color = color;
    this.brand = brand;
    this.run = function () {
        console.log(this.brand + '在跑');
    };
}

// 创建实例
var car1 = new Car('red', 'BMW');
var car2 = new Car('blue', 'Audi');

访问对象成员 ​

javascript
// 访问属性
car.color;              // 点语法(推荐)
car['color'];           // 方括号语法(属性名含特殊字符时用)

// 访问方法
car.run();
car['run']();

this 关键字 ​

代表当前对象,谁调用就指向谁。

静态成员 ​

不需要创建实例对象就能使用的属性和方法。

javascript
function Car() {}
Car.wheelCount = 4;  // 静态属性
console.log(Car.wheelCount);  // 直接通过构造函数访问

3.3 遍历对象与成员判断 ​

遍历对象:for...in ​

javascript
var person = {
    name: '张三',
    age: 18,
    sayHi: function () {
        console.log('hi');
    }
};

for (var key in person) {
    console.log(key);           // 属性名/方法名
    console.log(person[key]);   // 属性值/方法
}

判断成员是否存在:in 运算符 ​

javascript
console.log('name' in person);  // true
console.log('gender' in person); // false

3.4 JSON数据格式 ​

JSON(JavaScript Object Notation):JavaScript 对象标记法。

  • 独立于语言,适用于多种编程语言
  • 便于阅读和书写的数据交换格式
  • 主要用于存储和传输数据

JSON 对象格式:

json
{
    "name": "张三",
    "age": 18,
    "hobbies": ["读书", "运动"]
}

⚠️ 注意:key 必须使用双引号,value 如果是字符串也用双引号。


3.5 内置对象 ​

JS 自带的、直接使用的对象,不需要自己编写。

📖 推荐查阅文档:MDN 官方文档 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

(1)Math 对象 ​

数学相关运算,不需要实例化(不是构造函数)。

语法作用示例
Math.round(n)四舍五入到整数Math.round(4.5) → 5
Math.floor(n)向下取整Math.floor(4.9) → 4
Math.ceil(n)向上取整Math.ceil(4.1) → 5
Math.abs(n)绝对值Math.abs(-5) → 5
Math.random()0~1之间的随机浮点数[0.0, 1.0)
Math.pow(x, y)x的y次幂Math.pow(10, 2) → 100
Math.sqrt(n)开平方Math.sqrt(9) → 3
Math.max(a,b,...)最大值
Math.min(a,b,...)最小值

生成指定范围随机整数:

javascript
// min ~ max 之间的随机整数(包含两端)
Math.floor(Math.random() * (max - min + 1) + min);

// 1 ~ max 之间的随机整数
Math.floor(Math.random() * max + 1);

(2)Date 日期对象 ​

需要实例化:new Date()

javascript
var date = new Date();  // 当前时间

常用方法:

方法说明
getFullYear()获取年份
getMonth()获取月份(0-11,注意+1)
getDate()获取日期
getDay()获取星期几(0-6,0是周日)
getHours()获取小时
getMinutes()获取分钟
getSeconds()获取秒数
getTime()获取时间戳(毫秒)
valueOf()获取时间戳(毫秒)

时间戳: 从1970-01-01 00:00:00到当前时间的毫秒数 1秒 = 1000毫秒

(3)Array 数组对象 ​

数组类型检测:

javascript
var arr = [1, 2, 3];
arr instanceof Array;    // true(方式1)
Array.isArray(arr);      // true(方式2,推荐)

添加/删除元素:

方法作用返回值
push(元素)末尾添加元素新数组长度
unshift(元素)开头添加元素新数组长度
pop()删除末尾一个元素被删除的元素
shift()删除开头一个元素被删除的元素

数组排序:

javascript
arr.reverse();  // 颠倒顺序
arr.sort();     // 排序(默认按字符编码,数字排序需传函数)

// 数字升序排序
arr.sort(function (a, b) {
    return a - b;
});

数组索引:

方法作用
indexOf(元素)查找第一个匹配的索引,找不到返回-1
lastIndexOf(元素)查找最后一个匹配的索引,找不到返回-1

数组转字符串:

javascript
arr.toString();     // 用逗号连接
arr.join('分隔符'); // 用指定分隔符连接

其他方法:

方法作用
fill(值, start, end)用固定值填充数组
splice(开始, 删除个数, 插入元素)删除/插入/替换元素
slice(begin, end)截取数组(不改变原数组)
concat(arr2, ...)合并多个数组(不改变原数组)

遍历数组方法(6个):

javascript
// forEach:遍历每个元素,执行操作(无返回值)
arr.forEach(function (value, index, array) {
    console.log(value);
});

// map:遍历每个元素,返回新数组
var newArr = arr.map(function (value) {
    return value * 2;
});

// filter:过滤,返回符合条件的新数组
var result = arr.filter(function (value) {
    return value > 10;
});

// reduce:累计计算
var sum = arr.reduce(function (prev, curr) {
    return prev + curr;
}, 0);

// some:是否有至少一个满足条件(返回布尔值)
arr.some(function (value) {
    return value > 10;
});

// every:是否全部满足条件(返回布尔值)
arr.every(function (value) {
    return value > 10;
});

(4)String 字符串对象 ​

创建:

javascript
var str1 = new String('hello');  // 方式1
var str2 = 'hello';              // 方式2(推荐)

属性:

  • length:字符串长度

根据字符找位置:

方法作用
indexOf(value, start)从开头查找首次出现的位置,找不到返回-1
lastIndexOf(value, start)从末尾查找最后出现的位置,找不到返回-1

根据位置找字符:

方法作用
str[index]方括号索引访问
str.charAt(index)获取指定位置的字符
str.charCodeAt(index)获取指定位置字符的Unicode编码

其他常用方法:

方法作用
concat(str2, ...)连接多个字符串
toLowerCase()转小写
toUpperCase()转大写
split(分隔符)按分隔符分割成数组
replace(旧, 新)替换字符串
trim()删除前后空白字符
trimStart()删除开头空白
trimEnd()删除末尾空白
substring(start, end)截取字符串
substr(start, length)截取指定长度

3.6 值类型与引用类型 ​

类型包含赋值方式特点
值类型(基本类型)Number、String、Boolean、Null、Undefined赋值传值复制一份,互不影响
引用类型Object、Array、Function等赋值传址传递内存地址,修改会影响原变量
javascript
// 值类型
var a = 10;
var b = a;
a = 20;
console.log(b);  // 10(不受影响)

// 引用类型
var arr1 = [1, 2, 3];
var arr2 = arr1;
arr1.push(4);
console.log(arr2);  // [1,2,3,4](被影响了)

垃圾回收机制: JS 有自动垃圾回收机制,会自动释放不再使用的内存。


3.7 正则表达式 ​

正则表达式是描述字符串结构的语法规则,用于匹配字符串中的字符模式。

创建正则表达式 ​

javascript
// 方式1:字面量(推荐)
var reg = /表达式/附加参数;

// 方式2:构造函数
var reg = new RegExp('表达式', '附加参数');

附加参数:

  • g:全局匹配
  • i:忽略大小写

正则操作方法 ​

方法作用返回值
test()检测是否匹配true / false
exec()检索匹配结果数组 / null
compile()编译正则

正则表达式语法 ​

方括号(字符类):

表达式描述
[abc]匹配a、b、c中的任意1个字符
[^abc]匹配不在a、b、c中的任意1个字符
[0-9]匹配0到9的任意1个数字
[a-z]匹配任意1个小写字母
[A-Z]匹配任意1个大写字母
[a-zA-Z]匹配任意1个字母

量词:

符号描述示例
*前面的字符出现0次或多次/a*b/ 可匹配 b、ab、aaab
+前面的字符出现1次或多次/a+b/ 可匹配 ab、aaab
?前面的字符出现0次或1次/a?b/ 可匹配 b、ab
{n}前面的字符连续出现n次/a{3}/ 相当于 aaa
{n,}前面的字符连续出现至少n次/a{3,}/
{n,m}前面的字符连续出现n到m次/a{1,3}/

常用符号:

符号描述
^匹配字符串的开始
$匹配字符串的结束
\d匹配一个数字字符,等价于 [0-9]
\D匹配非数字字符,等价于 [^0-9]
\w匹配数字、下划线或字母,等价于 [A-Za-z0-9_]
\W匹配非单字字符
\s匹配任意空白字符
\S匹配任意非空白字符
.匹配除换行符外的任意字符
|或

常用正则示例:

javascript
// 用户名:英文字母和数字组成的4-16位字符,以字母开头
var userReg = /^[a-zA-Z][a-zA-Z0-9]{3,15}$/;

// 邮箱验证
var emailReg = /^\w+@\w+\.(com|cn)$/;

// 手机号验证
var phoneReg = /^1[3-9]\d{9}$/;

第四章 BOM与DOM ​

4.1 API与Web API ​

API(Application Programming Interface):应用程序接口。 实现某种功能,开发人员无须访问源码、无须理解内部实现机制,只需要知道怎么用即可。

Web API: 操作浏览器和网页的接口集合。

  • DOM:文档对象模型,操作网页元素
  • BOM:浏览器对象模型,操作浏览器窗口

4.2 DOM概述 ​

DOM(Document Object Model):文档对象模型。

操作网页元素的标准接口,可以获取元素、修改属性、操作样式、绑定事件等。

DOM树: 将HTML文档看成树结构。

document(文档)
└── html
    ├── head
    │   └── title
    └── body
        ├── div
        └── p

节点(node): 网页中的所有内容在DOM树中都是节点。

  • 元素节点(标签)
  • 属性节点
  • 文本节点
  • 注释节点

4.3 获取页面元素 ​

(1)通过 ID 获取 ​

javascript
var box = document.getElementById('box');

返回单个元素对象。

(2)通过标签名获取 ​

javascript
var lis = document.getElementsByTagName('li');

返回伪数组(HTMLCollection),用索引访问单个元素。

(3)通过 name 获取 ​

javascript
var fruits = document.getElementsByName('fruit');

返回伪数组,常用于表单元素。

(4)通过类名获取(HTML5) ​

javascript
var items = document.getElementsByClassName('item');

返回伪数组。

(5)querySelector(HTML5,推荐) ​

返回指定CSS选择器匹配的第一个元素。

javascript
document.querySelector('#box');       // ID选择器
document.querySelector('li');          // 标签选择器
document.querySelector('.item');       // 类选择器
document.querySelector('div > p');     // 后代选择器

(6)querySelectorAll(HTML5,推荐) ​

返回指定CSS选择器匹配的所有元素(伪数组)。

javascript
document.querySelectorAll('.item');

document 对象常用属性 ​

javascript
document.title          // 页面标题
document.body           // body元素
document.documentElement // html元素
document.forms          // 所有表单
document.images         // 所有图片

4.4 操作元素内容 ​

属性说明特点
innerHTML获取/设置元素内容保留标签、空格、换行
innerText获取/设置元素文本去掉标签,去掉空格换行
textContent获取/设置元素文本去掉标签,保留空格换行
javascript
var box = document.getElementById('box');

// 获取
console.log(box.innerHTML);

// 设置
box.innerHTML = '<h1>新标题</h1>';

4.5 操作元素属性 ​

javascript
// 获取属性
元素.属性名

// 修改属性
元素.属性名 = '属性值';

常用属性: src、href、title、alt、id、className 等

javascript
var img = document.querySelector('img');
img.src = 'images/2.jpg';
img.title = '这是一张图片';

4.6 操作元素样式 ​

方式1:操作 style 属性 ​

javascript
元素.style.样式名 = '值';
javascript
var box = document.getElementById('box');
box.style.backgroundColor = 'red';
box.style.fontSize = '20px';
box.style.display = 'none';  // 隐藏元素

⚠️ 注意:JS中样式名用驼峰命名,如 backgroundColor、fontSize

方式2:操作 className 属性 ​

javascript
元素.className = '类名';

通过修改类名,批量改变样式(推荐用于样式较多的情况)。


4.7 自定义属性与data-* ​

获取属性 ​

javascript
// 通用方式(推荐,适用于所有属性)
element.getAttribute('属性名');

// 内置属性也可以用点语法
element.id;

设置属性 ​

javascript
// 通用方式(推荐)
element.setAttribute('属性名', '属性值');

// 内置属性也可以用点语法
element.id = 'newId';

移除属性 ​

javascript
element.removeAttribute('属性名');

H5 自定义属性 data-* ​

H5 规定用 data-属性名 的方式设置自定义属性。

javascript
// 设置
element.setAttribute('data-index', '1');
element.dataset.index = '1';  // 另一种方式

// 获取
element.getAttribute('data-index');
element.dataset.index;

4.8 DOM节点操作 ​

节点层级关系 ​

  • 根节点:document
  • 父节点:parentNode
  • 子节点:children
  • 兄弟节点:nextElementSibling、previousElementSibling

获取父节点 ​

javascript
元素.parentNode

获取子节点 ​

javascript
// 推荐:获取所有子元素节点(伪数组)
元素.children

// 第一个子元素
元素.children[0]

// 最后一个子元素
元素.children[元素.children.length - 1]

获取兄弟节点 ​

javascript
元素.nextElementSibling       // 下一个兄弟元素
元素.previousElementSibling   // 上一个兄弟元素

创建节点 ​

javascript
document.createElement('标签名');

添加节点 ​

javascript
// 在末尾添加
父元素.appendChild(子节点);

// 在指定节点前添加
父元素.insertBefore(新节点, 指定节点);

删除节点 ​

javascript
父元素.removeChild(子节点);

// 删除自己
node.parentNode.removeChild(node);

复制节点 ​

javascript
元素.cloneNode(true);   // 深拷贝,复制内容
元素.cloneNode(false);  // 浅拷贝,只复制标签

4.9 事件基础 ​

事件: 可以被JS检测到的行为,是一种"触发-响应"机制。

事件三要素 ​

  1. 事件源:触发事件的元素(谁触发了事件)
  2. 事件类型:什么事件(如 click、mouseover)
  3. 事件处理程序:触发后执行的代码(做什么)

常用事件类型 ​

事件名触发时机
onclick鼠标单击
onfocus获得焦点
onblur失去焦点
onmouseover鼠标经过
onmouseout鼠标离开
onmousemove鼠标移动
onmousedown鼠标按下
onmouseup鼠标抬起
onkeydown键盘按下
onkeypress键盘按下(不识别功能键)
onkeyup键盘松开
onload页面加载完成
onchange内容改变
onselect文本被选中
onsubmit表单提交

传统绑定事件方式 ​

javascript
元素.onclick = function () {
    // 事件处理代码
};

⚠️ 传统方式:同一个元素同一个事件只能绑定一个处理函数,后绑定的会覆盖前面的。

排他思想 ​

排除掉其他的(包括自己),然后给自己设置效果。

javascript
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {
    btns[i].onclick = function () {
        // 1. 先把所有按钮的样式去掉
        for (var j = 0; j < btns.length; j++) {
            btns[j].style.backgroundColor = '';
        }
        // 2. 给当前点击的按钮加样式
        this.style.backgroundColor = 'red';
    };
}

4.10 事件进阶 ​

事件监听(推荐) ​

同一个元素同一个事件可以绑定多个处理函数。

javascript
元素.addEventListener('事件类型', 处理函数);
javascript
var btn = document.getElementById('btn');
btn.addEventListener('click', function () {
    console.log('第一个处理函数');
});
btn.addEventListener('click', function () {
    console.log('第二个处理函数');
});

💡 事件类型不带 on 前缀,如 click、mouseover

删除事件 ​

javascript
// 传统方式
元素.onclick = null;

// 事件监听方式
元素.removeEventListener('事件类型', 处理函数名);

DOM 事件流 ​

事件传播分为三个阶段:

  1. 捕获阶段:从父到子(从外向内)
  2. 目标阶段:到达事件源
  3. 冒泡阶段:从子到父(从内向外)

事件对象 ​

与触发事件相关的所有信息,参数 event(或 e)就是事件对象。

javascript
元素.addEventListener('click', function (e) {
    console.log(e);  // 事件对象
});

事件对象常用属性/方法:

属性/方法说明
e.target触发事件的对象(标准浏览器)
e.srcElement触发事件的对象(IE6-8)
e.type事件类型(如 click,不带on)
e.keyCode键盘按键码
e.stopPropagation()阻止事件冒泡
e.cancelBubble阻止事件冒泡(IE6-8)
e.preventDefault()阻止默认行为(如链接跳转)
e.pageX / e.pageY鼠标在文档中的坐标
e.clientX / e.clientY鼠标在可视区的坐标

e.target 与 this 的区别:

  • e.target:触发事件的对象(实际点击的元素)
  • this:绑定事件的对象

阻止事件冒泡 ​

javascript
e.stopPropagation();  // 标准浏览器
e.cancelBubble = true; // IE6-8

阻止默认行为 ​

javascript
e.preventDefault();  // 标准浏览器

事件委托 ​

不给子元素绑定事件,给父元素绑定事件,利用事件冒泡原理。

优点:减少事件绑定数量,提高性能。

javascript
// 给ul绑定事件,点击li也能触发
document.querySelector('ul').addEventListener('click', function (e) {
    if (e.target.tagName === 'LI') {
        console.log('点击了li');
    }
});

键盘事件 ​

执行顺序:keydown → keypress → keyup

  • keydown:按键按下触发(识别所有键)
  • keypress:按键按下触发(不识别功能键,区分大小写)
  • keyup:按键松开触发

keyCode: 按键的ASCII码值

  • keypress:区分大小写(大写65-90,小写97-122)
  • keydown/keyup:字母键都以大写显示(65-90)

表单相关 ​

javascript
// 获取/设置输入框内容
元素.value

// 获取/设置元素HTML内容
元素.innerHTML

4.11 BOM概述 ​

BOM(Browser Object Model):浏览器对象模型。

与浏览器窗口交互的对象集合,核心对象是 window。

window(顶级对象)
├── document(文档)
├── location(URL相关)
├── navigator(浏览器信息)
├── history(历史记录)
└── screen(屏幕信息)

4.12 window对象 ​

window 是浏览器的顶级对象,代表浏览器窗口。

常见属性 ​

属性描述
innerWidth窗口文档显示区宽度
innerHeight窗口文档显示区高度
name窗口名称
closed窗口是否已关闭
screenLeft / screenTop窗口左上角在屏幕的坐标
opener打开当前窗口的父窗口
parent父窗口(框架用)
self当前窗口对象本身

常见事件 ​

javascript
// 页面加载完成事件
window.onload = function () {
    // 页面所有资源加载完后执行
};

// 窗口大小改变事件
window.onresize = function () {
    // 窗口大小改变时触发
};

常见方法 ​

javascript
// 打开新窗口
window.open(URL, name, features, replace);

// 关闭窗口
window.close();

open 参数说明:

  • URL:打开的页面地址
  • name:窗口名称(_blank 新窗口、_self 当前页)
  • features:窗口特征(宽、高、位置、菜单栏等)

模态对话框 ​

javascript
alert('信息');        // 警告框
confirm('确认吗?');   // 确认框,返回true/false
prompt('请输入');      // 输入框,返回输入内容

4.13 定时器 ​

设置定时器 ​

javascript
// 一次性定时器:指定毫秒后执行一次
setTimeout(函数, 毫秒数);

// 周期性定时器:每隔指定毫秒执行一次
setInterval(函数, 毫秒数);

清除定时器 ​

javascript
clearTimeout(定时器ID);    // 清除一次性定时器
clearInterval(定时器ID);   // 清除周期性定时器
javascript
// 示例
var timer = setTimeout(function () {
    console.log('3秒后执行');
}, 3000);

// 清除
clearTimeout(timer);

4.14 JS执行机制 ​

单线程 ​

JS 是单线程的,同一时间只能做一件事。

同步与异步 ​

  • 同步:前一个任务结束后再执行后一个任务(排队执行)
  • 异步:做一件事的同时,可以做其他事情

异步任务举例: click事件、setTimeout、setInterval、AJAX请求等

执行机制:

  1. 先执行所有同步任务
  2. 异步任务放入任务队列
  3. 同步任务执行完后,依次执行任务队列中的异步任务

4.15 location对象 ​

URL 相关信息。

URL 组成示例:

https://www.baidu.com:443/path/index.html?id=1&name=2#hash
\_____/   \_________/ \__/ \____________/ \___________/ \___/
  协议       主机名    端口      路径          参数        锚点

常用属性:

属性说明
href完整URL
protocol协议
host主机+端口
hostname主机名
port端口
pathname路径
search查询参数(?后面的)
hash锚点(#后面的)

常用方法:

方法说明
assign(url)载入新页面(有历史记录)
replace(url)替换当前页面(无历史记录)
reload()重新加载(刷新)

4.16 history对象 ​

浏览器历史记录。

属性/方法说明
length历史记录数量
back()后退
forward()前进
go(n)跳转到第n条记录(正数前进,负数后退)

4.17 navigator对象 ​

浏览器信息。

常用属性: appCodeName、appName、appVersion、platform

常用方法: javaEnabled()


4.18 Web Storage ​

HTML5 新增的客户端存储方案,比 Cookie 更直观。

sessionStorage ​

临时保存同一窗口(标签页)的数据,关闭窗口即清除。

特点:

  • 只在本地生效,关闭标签页清除
  • key-value 存储,value 必须是字符串
  • 存储上限约 5MB
javascript
// 保存
sessionStorage.setItem('key', 'value');

// 获取
sessionStorage.getItem('key');

// 删除
sessionStorage.removeItem('key');

// 清空所有
sessionStorage.clear();

localStorage ​

永久保存在本地,关闭浏览器也不会消失,除非手动清除。

特点:

  • 永久存储,同源窗口共享
  • 只能存字符串
  • 存储上限约 5MB
javascript
// 保存
localStorage.setItem('key', 'value');

// 获取
localStorage.getItem('key');

// 删除
localStorage.removeItem('key');

// 清空所有
localStorage.clear();

三者对比 ​

特性localStoragesessionStorageCookie
存储容量约5-10MB约5-10MB约4KB
持久性永久会话级(关标签页清除)可设置过期时间
共享范围同源所有窗口共享仅限当前窗口同源所有窗口共享
与服务器通信不会自动发送不会自动发送每次请求自动携带
用途永久保存用户数据临时保存会话数据身份验证、Session ID

第五章 JS网页特效 ​

5.1 偏移量 offset ​

属性作用包含
offsetLeft相对有定位父元素左边框的偏移—
offsetTop相对有定位父元素上边框的偏移—
offsetWidth自身宽度padding + border + 内容
offsetHeight自身高度padding + border + 内容
offsetParent返回带定位的父元素—

💡 如果父元素没有定位,则相对于 body。

offset 与 style 的区别:

  • offset 可以获取任意样式表中的样式值
  • offset 获取的是数值型(不带单位)
  • offset 是只读属性,不能赋值
  • style 只能获取行内样式,可读写

5.2 可视区 client ​

属性作用包含不包含
clientLeft左边框宽度border-leftpadding、margin、内容
clientTop上边框高度border-toppadding、margin、内容
clientWidth可视宽度内容 + 左右paddingborder、margin、滚动条
clientHeight可视高度内容 + 上下paddingborder、margin、滚动条

5.3 滚动 scroll ​

属性作用包含不包含
scrollWidth总内容宽度所有内容 + 左右paddingborder、margin
scrollHeight总内容高度所有内容 + 上下paddingborder、margin
scrollLeft被卷去的左侧距离滚动条偏移量—
scrollTop被卷去的上方距离滚动条偏移量—

页面滚动事件:

javascript
window.onscroll = function () {
    console.log(window.pageYOffset);  // 页面被卷去的顶部距离
};

第六章 ES6新特性 ​

6.1 ES6概述 ​

ES6(ECMAScript 6)是 JavaScript 语言的新标准,2015年6月正式发布,也叫 ES2015。

引入了大量新语法特性,使 JS 更现代化、易读、易维护,更适合企业级开发。


6.2 let 与 const ​

let 命令 ​

声明变量,只在代码块内有效(块级作用域)。

javascript
{
    let a = 10;
    var b = 1;
}
console.log(a);  // ReferenceError: a is not defined
console.log(b);  // 1

let vs var:

  • let 有块级作用域,var 没有
  • let 不存在变量提升,var 有
  • let 有暂时性死区
  • let 不允许重复声明

const 命令 ​

声明只读的常量,一旦声明,值不能改变。

javascript
const PI = 3.1415;
PI = 3;  // TypeError: Assignment to constant variable.

⚠️ const 声明时必须赋值;如果是对象,对象的属性可以修改(因为地址不变)。


6.3 模板字符串 ​

增强版的字符串,用反引号 ` 标识。

特点:

  • 可以当普通字符串使用
  • 可以定义多行字符串
  • 可以在字符串中嵌入变量(${变量})
javascript
let name = '张三';
let age = 18;

// 嵌入变量
let str = `${name}的年龄是${age}岁`;

// 多行字符串
let html = `
    <div>
        <h1>标题</h1>
        <p>内容</p>
    </div>
`;

6.4 对象与方法简写 ​

属性简写 ​

javascript
const age = 12;
const name = 'Amy';

// 简写
const person = { age, name };
// 等同于
const person = { age: age, name: name };

方法简写 ​

javascript
const person = {
    sayHi() {
        console.log('Hi');
    }
};
// 等同于
const person = {
    sayHi: function () {
        console.log('Hi');
    }
};

6.5 箭头函数 ​

更加简洁的函数书写方式。

语法: 参数 => 函数体

javascript
// 普通函数
var fn1 = function (a, b) {
    return a + b;
};

// 箭头函数
var fn2 = (a, b) => {
    return a + b;
};

简化规则:

  • 只有一个参数时,括号可以省略
  • 没有参数时,括号不能省略
  • 函数体只有一行 return 语句时,大括号和 return 可以省略
传统定义箭头函数描述
function() {}() => {}无参
function(a) {}a => {}单个参数
function(a, b) {}(a, b) => {}多个参数
function(a, ...args) {}(a, ...args) => {}可变参数

⚠️ 箭头函数没有自己的 this,它的 this 继承自外层作用域。


6.6 解构赋值 ​

数组解构 ​

javascript
let [a, b, c] = [1, 2, 3];
// a=1, b=2, c=3

对象解构 ​

javascript
const { name, age } = { name: 'John', age: 20 };
// name='John', age=20

6.7 数组扩展方法 ​

数组创建 ​

Array.from(): 将伪数组/可遍历对象转为真正的数组

javascript
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
let arr = Array.from(arrayLike);  // ['a', 'b', 'c']

Array.of(): 将一组值转为数组

javascript
Array.of(3, 11, 8);  // [3, 11, 8]

数据筛选 ​

方法作用
find(回调)找出第一个符合条件的成员
findIndex(回调)找出第一个符合条件的成员的索引,找不到返回-1
filter(回调)返回符合条件的全部成员(新数组)
some(回调)是否有至少一个满足条件(布尔值)
every(回调)是否全部满足条件(布尔值)
javascript
var nums = [2, 6, 22, 55];

nums.find(v => v > 9);       // 22
nums.filter(v => v > 9);     // [22, 55]
nums.some(v => v > 50);      // true
nums.every(v => v > 10);     // false

数据填充 ​

fill(): 用给定值填充数组

javascript
// 创建长度为5、全为1的数组
const arr = new Array(5).fill(1);  // [1, 1, 1, 1, 1]

// 填充指定位置
arr.fill(7, 1, 4);  // 索引1~3填充为7(不包含4)

数据遍历 ​

方法作用
keys()遍历键名(索引)
values()遍历键值
entries()遍历键值对
javascript
let arr = ['小红', '小明', '小芳'];

for (let index of arr.keys()) {
    console.log(index);  // 0, 1, 2
}

for (let value of arr.values()) {
    console.log(value);  // 小红, 小明, 小芳
}

for (let [index, value] of arr.entries()) {
    console.log(index + ':' + value);  // 0:小红, 1:小明, 2:小芳
}

includes ​

判断数组是否包含给定值,返回布尔值。

javascript
[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 2);  // true(从索引2开始找)

flat ​

将嵌套数组"拉平",下降一个维度。

javascript
[1, 2, [3, [4, 5]]].flat();         // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat().flat();  // [1, 2, 3, 4, 5]

6.8 Set 数据结构 ​

类似于数组,但成员值唯一,没有重复。

javascript
const s = new Set();
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
// s = {2, 3, 5, 4}

const items = new Set([1, 2, 3, 4, 5, 5, 5]);
items.size;  // 5(自动去重)

常用方法:

方法描述
size成员总数
add(value)添加值,返回Set本身
delete(value)删除值,返回布尔值
has(value)是否包含,返回布尔值
clear()清除所有成员
keys() / values()返回遍历器
entries()返回键值对遍历器
forEach()遍历每个成员

数组去重技巧:

javascript
let arr = [1, 2, 2, 3, 3, 3];
let unique = [...new Set(arr)];  // [1, 2, 3]

6.9 Map 数据结构 ​

键值对集合,键可以是任意类型(比 Object 更灵活)。

javascript
const map = new Map();
map.set('a', 1);
map.set('b', 2);

map.get('a');    // 1
map.set('a', 97);  // 覆盖
map.get('a');    // 97
map.size;        // 2
map.delete('b'); // true

常用方法:

方法描述
size成员总数
set(key, value)设置键值对,返回Map本身(可链式)
get(key)读取值,找不到返回undefined
has(key)是否存在键,返回布尔值
delete(key)删除键,返回布尔值
clear()清除所有成员
keys()返回键名遍历器
values()返回键值遍历器
entries()返回所有成员遍历器
forEach()遍历所有成员

6.10 Class 类与继承 ​

ES6 引入了 Class(类)的概念,通过 class 关键字定义类。

类的基本语法 ​

javascript
class Point {
    // 构造方法
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    // 方法
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}

// 创建实例
var point = new Point(2, 3);
console.log(point.toString());  // (2, 3)

💡 constructor 是构造方法,this 代表实例对象。 类实质上就是一个函数,类自身指向构造函数。

类的继承 ​

通过 extends 关键字实现继承。

super 关键字:在子类中调用父类的构造函数和方法。

javascript
class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);  // 调用父类构造函数
        this.breed = breed;
    }
    speak() {
        super.speak();  // 调用父类方法
        console.log(`${this.name} is a ${this.breed}.`);
    }
}

静态方法 ​

通过 static 关键字定义,不需要创建实例就能直接调用。

javascript
class Foo {
    static classMethod() {
        return 'hello';
    }
}

Foo.classMethod();  // 'hello'(直接通过类名调用)

教程结束

学习建议:

  1. 每学完一章,动手敲代码练习
  2. 多做小项目,如计算器、轮播图、TodoList
  3. 善用 MDN 文档查阅 API
  4. 学会调试:console.log + 断点调试

基于 Vite 强力驱动 | 纯静态轻量托管