JavaScript 标准教程
目录
-
(图片来源网络,侵删)- 1 什么是 JavaScript?
- 2 第一个 JavaScript 程序
- 3 变量与数据类型
- 4 运算符
- 5 流程控制
- 6 函数
- 7 对象与数组
-
- 1 作用域与闭包
- 2
this关键字 - 3 原型与原型链
- 4 异步编程:回调、Promise 与 Async/Await
- 5 ES6+ 新特性精要
-
第三部分:浏览器中的 JavaScript (DOM & BOM)
- 1 DOM (文档对象模型) 操作
- 2 BOM (浏览器对象模型) 简介
- 3 事件处理
-
- 1 包管理器 (npm/yarn)
- 2 模块化开发 (ES Modules)
- 3 构建工具 (Webpack/Vite) 简介
- 4 代码规范与格式化 (ESLint, Prettier)
-
(图片来源网络,侵删)- 1 推荐书籍
- 2 推荐网站与教程
- 3 实践项目
第一部分:JavaScript 基础
1 什么是 JavaScript?
JavaScript 是一种轻量级的、解释型的、或即时编译型的编程语言,它是一种基于原型、多范式的动态脚本语言,支持面向对象、命令式和函数式编程。
核心特点:
- 运行在浏览器端: 最初的目的是为网页增加交互性,实现动态效果。
- 动态类型: 变量的类型在运行时确定,不需要预先声明。
- 基于原型: JavaScript 没有传统的类,而是通过原型来实现继承。
- 单线程: 在浏览器中,JavaScript 是单线程的,但通过事件循环和异步回调机制(如
setTimeout,Promise)来实现非阻塞的 I/O 操作。
2 第一个 JavaScript 程序
在 HTML 文件中,通过 <script> 标签引入 JavaScript 代码。
index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">我的第一个 JS 程序</title>
</head>
<body>
<h1>你好,世界!</h1>
<p>打开浏览器的开发者工具查看控制台输出。</p>
<!-- 内联脚本 -->
<script>
console.log("Hello, JavaScript!");
alert("欢迎来到 JavaScript 世界!");
</script>
<!-- 也可以引入外部 JS 文件 -->
<!-- <script src="app.js"></script> -->
</body>
</html>
console.log(): 在控制台打印信息,是调试代码最重要的工具。alert(): 弹出一个对话框,会阻塞页面,不推荐在生产环境中使用。
3 变量与数据类型
变量声明 (ES6+ 推荐):
let: 声明一个块级作用域的变量,可以重新赋值。const: 声明一个块级作用域的常量,声明后不能重新赋值(但对象和数组的内部内容可以修改)。var: 旧时代的声明方式,存在函数作用域和变量提升问题,不推荐在新的项目中使用。
let name = "张三"; // 字符串
const age = 25; // 数字
let isStudent = true; // 布尔值
let hobbies = ["reading", "coding"]; // 数组
let person = { name: "李四", age: 30 }; // 对象
let nothing = null; // 空值
let notDefined; // undefined
console.log(typeof name); // "string"
console.log(typeof age); // "number"
基本数据类型:
String: 字符串。Number: 数字,包括整数和浮点数。Boolean: 布尔值,true或false。Undefined: 变量已声明但未赋值。Null: 表示“没有值”或“空值”。Symbol (ES6): 表示独一无二的值。BigInt (ES11): 表示任意精度的整数。
引用数据类型:
Object: 对象,是复杂数据类型,可以存储多个属性和方法。Array: 数组,一种特殊的对象,用于存储有序的值列表。Function: 函数,也是对象的一种。
4 运算符
- 算术运算符: , , , , (取余), ,
- 赋值运算符: , , , ,
- 比较运算符: (宽松相等), (严格相等), , ,
>,<,>=,<=- 重要: 尽量使用 和 ,因为它不会进行类型转换,更安全。
- 逻辑运算符:
&&(与), (或), (非) - 三元运算符:
condition ? value_if_true : value_if_false
let a = 10; let b = "10"; console.log(a == b); // true (因为会进行类型转换) console.log(a === b); // false (因为类型和值都不同) let score = 85; let grade = score > 90 ? 'A' : score > 80 ? 'B' : 'C'; console.log(grade); // "B"
5 流程控制
条件语句:
let hour = new Date().getHours();
if (hour < 12) {
console.log("早上好!");
} else if (hour < 18) {
console.log("下午好!");
} else {
console.log("晚上好!");
}
循环语句:
for: 循环次数已知。while: 循环条件未知,先判断后执行。do...while: 先执行一次,再判断。for...of: 遍历可迭代对象(如数组、字符串)。for...in: 遍历对象的可枚举属性。
// for 循环
for (let i = 0; i < 5; i++) {
console.log("循环次数: " + i);
}
// for...of 遍历数组
let fruits = ["apple", "banana", "cherry"];
for (const fruit of fruits) {
console.log(fruit);
}
// for...in 遍历对象
let car = { brand: "Toyota", model: "Camry", year: 2025 };
for (const key in car) {
console.log(key + ": " + car[key]);
}
6 函数
函数是可重复执行的代码块。
// 函数声明
function greet(name) {
return `你好, ${name}!`;
}
// 函数表达式
const add = function(a, b) {
return a + b;
};
// 箭头函数 (ES6+) - 更简洁的函数表达式
const multiply = (a, b) => a * b;
console.log(greet("世界")); // "你好, 世界!"
console.log(add(3, 5)); // 8
console.log(multiply(4, 5)); // 20
7 对象与数组
对象:
对象的键名通常是字符串,也可以是 Symbol。
let user = {
name: "王五",
age: 28,
sayHello: function() {
console.log(`我的名字是 ${this.name}`);
}
};
// 访问属性
console.log(user.name); // "王五"
console.log(user['age']); // 28
// 修改属性
user.age = 29;
// 调用方法
user.sayHello(); // "我的名字是 王五"
// 添加新属性
user.email = "wangwu@example.com";
数组:
let colors = ["red", "green", "blue"];
// 访问元素
console.log(colors[0]); // "red"
// 修改元素
colors[1] = "yellow";
// 常用数组方法
colors.push("black"); // 末尾添加
colors.pop(); // 删除末尾
colors.shift(); // 删除开头
colors.unshift("white"); // 开头添加
console.log(colors.length); // 4
第二部分:进阶核心概念
1 作用域与闭包
- 作用域: 变量可访问的范围,JavaScript 有全局作用域、函数作用域和块级作用域(
let/const创建)。 - 闭包: 函数和其周围状态(词法环境)的引用捆绑在一起,换句话说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。
function outer(x) {
// x 是 outer 函数的局部变量
function inner(y) {
// inner 函数可以访问 outer 函数的变量 x
return x + y;
}
return inner; // 返回 inner 函数
}
const addFive = outer(5); // addFive 现在是 inner 函数
console.log(addFive(3)); // 输出 8
2 this 关键字
this 的值在函数被调用时确定,而不是在函数定义时。
- 在全局作用域中:
this指向全局对象(在浏览器中是window)。 - 作为对象方法调用:
this指向该对象。 - 作为普通函数调用:
this指向全局对象(严格模式下是undefined)。 - 使用
call,apply,bind: 可以显式地改变this的指向。 - 箭头函数: 没有自己的
this,它会继承外层作用域的this。
const obj = {
name: "我的对象",
sayThis: function() {
console.log(this); // this 指向 obj
}
};
obj.sayThis();
function foo() {
console.log(this); // 在非严格模式下指向 window
}
foo();
3 原型与原型链
JavaScript 的对象继承是基于原型的,每个对象都有一个内部链接指向另一个对象,这个对象就是它的原型。
__proto__: 实例对象的隐式原型。prototype: 构造函数的显式原型,用于创建实例对象时共享属性和方法。
// 使用构造函数创建对象
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} 发出声音`);
};
const dog = new Animal("旺财");
dog.speak(); // "旺财 发出声音"
console.log(dog.__proto__ === Animal.prototype); // true
4 异步编程
JavaScript 是单线程的,异步编程是处理耗时操作(如网络请求、文件读写)的关键。
- 回调函数: 将一个函数作为参数传递给另一个函数,在任务完成后执行。
- 缺点: 容易陷入“回调地狱”(Callback Hell),代码难以维护。
- Promise: 代表一个异步操作的最终完成或失败,它有三种状态:
pending(进行中),fulfilled(已成功),rejected(已失败)。 - Async/Await: 是 Promise 的语法糖,让异步代码看起来更像同步代码,更易读。
// Promise 示例
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("数据获取成功!");
} else {
reject("数据获取失败!");
}
}, 1000);
});
}
// 使用 .then() 和 .catch()
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
// 使用 Async/Await
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
getData();
5 ES6+ 新特性精要
let和const: 块级作用域变量声明。- 箭头函数: 更简洁的
this绑定。 - 模板字符串: 使用反引号
`创建多行字符串和嵌入变量。 - 解构赋值: 从数组或对象中快速提取值。
- 默认参数: 为函数参数设置默认值。
- 对象/数组展开运算符 (): 复制或合并数组/对象。
class语法: 基于原型的面向对象编程的“语法糖”,更易理解。
// 解构赋值
const [a, b] = [1, 2];
const { name, age } = { name: "赵六", age: 40 };
// 模板字符串
const message = `你好, ${name}, 你今年 ${age} 岁了,`;
// 默认参数
function greet(name = "访客") {
console.log(`你好, ${name}!`);
}
// 展开运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// Class
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`你好, 我是 ${this.name}`);
}
}
const p = new Person("钱七", 50);
p.greet();
第三部分:浏览器中的 JavaScript (DOM & BOM)
1 DOM (文档对象模型) 操作
DOM 是 HTML 和 XML 文档的编程接口,它将文档表示为一个树形结构,JavaScript 可以通过 DOM API 来动态地修改页面内容、结构和样式。
// 获取元素
const title = document.querySelector("h1");
const button = document.getElementById("myButton");
title.textContent = "标题已修改!";
// 修改样式style.color = "blue";
// 添加事件监听器
button.addEventListener("click", () => {
alert("按钮被点击了!");
});
2 BOM (浏览器对象模型) 简介
BOM 允许 JavaScript 与浏览器进行交互。
window: 浏览器窗口,是 BOM 的核心。location: 获取或修改当前页面的 URL。history: 浏览历史记录。alert(),confirm(),prompt(): 弹出对话框。
// 获取当前 URL
console.log(window.location.href);
// 跳转到新页面
// window.location.href = "https://www.example.com";
// 获取窗口尺寸
console.log(`窗口宽度: ${window.innerWidth}, 高度: ${window.innerHeight}`);
3 事件处理
事件是用户或浏览器自身执行的某种动作,JavaScript 可以“监听”这些事件并做出响应。
- 事件冒泡: 事件从最具体的元素开始,逐级向上传播到不那么具体的元素。
- 事件捕获: 事件从最不具体的元素(
document)开始,逐级向下传播到目标元素。 - 事件委托: 利用事件冒泡,将事件监听器添加到父元素上,以处理子元素的事件,这可以提高性能,特别是当有大量动态生成的子元素时。
<ul id="parent-list">
<li>项目 1</li>
<li>项目 2</li>
<li>项目 3</li>
</ul>
<script>
const list = document.getElementById("parent-list");
// 事件委托:点击任何一个 li,都能触发事件
list.addEventListener("click", (event) => {
// 确保点击的是 li 元素
if (event.target.tagName === "LI") {
console.log("你点击了:", event.target.textContent);
}
});
</script>
第四部分:现代开发工具与工程化
1 包管理器
- npm (Node Package Manager): Node.js 自带的包管理器,也是目前最主流的 JavaScript 包管理器。
- yarn: 由 Facebook 推出的包管理器,速度更快,有更严格的锁文件机制。
- pnpm: 近年来非常流行的包管理器,通过硬链接和符号链接大幅节省磁盘空间和安装时间。
常用命令:
# 初始化项目 npm init -y # 安装包 npm install lodash # 安装开发依赖 npm install --save-dev webpack # 运行脚本 npm run build
2 模块化开发
模块化将代码分割成独立、可复用的文件。
- CommonJS: Node.js 默认的模块系统,使用
require()导入,module.exports导出。 - ES Modules (ESM): JavaScript 官方的模块化标准,使用
import导入,export导出,现代浏览器和 Node.js (v12+) 都已原生支持。
math.js (ESM)
export const add = (a, b) => a + b; export const PI = 3.14159;
main.js (ESM)
import { add, PI } from './math.js';
console.log(add(2, 3)); // 5
console.log(PI); // 3.14159
3 构建工具
构建工具(如 Webpack, Vite, Parcel)用于将多个 JavaScript 文件、CSS 文件、图片等资源打包成一个或少数几个文件,以优化加载性能。
- Webpack: 功能强大,配置复杂,社区生态成熟。
- Vite: 新一代前端构建工具,利用浏览器原生的 ES 模块支持,开发服务器启动和热更新速度极快。
4 代码规范与格式化
- ESLint: 一个插件化的 JavaScript 代码检查工具,可以帮助你发现并修复问题代码。
- Prettier: 一个“有主见”的代码格式化工具,可以统一整个团队的代码风格。
通常将两者结合使用,让 Prettier 负责格式化,ESLint 负责检查逻辑错误。
第五部分:学习路径与资源推荐
1 推荐书籍
- 《JavaScript 高级程序设计(第4版)》: 经典中的经典,内容全面且深入,适合系统学习和作为参考手册。
- 《你不知道的JavaScript(上/中/下卷)》: 深入讲解 JavaScript 的核心概念(作用域、闭包、
this、原型等),适合有一定基础后阅读,能让你真正“知道”JS。 - 《Eloquent JavaScript (JavaScript 权威指南)》: 一本优秀的在线书籍,理论与实践结合得很好,有大量练习题。
2 推荐网站与教程
- MDN Web Docs (developer.mozilla.org): JavaScript 学习的终极宝典,文档权威、准确、详尽,是每个前端开发者的必备网站。
- JavaScript.info: 现代且结构化的 JavaScript 教程,内容清晰易懂,从基础到高级一应俱全。
- freeCodeCamp: 提供大量免费的互动式编程课程,项目驱动,学习体验很好。
- W3Schools: 提供基础的教程和简单的在线实例,适合快速入门和查询。
3 实践项目
理论学习后,必须通过实践来巩固。
- 个人作品集网站: 用 HTML, CSS, JavaScript 创建一个展示自己技能和项目的网站。
- 待办事项列表: 练习 DOM 操作、事件处理和本地存储。
- 天气应用: 调用公开的天气 API,获取并展示天气数据。
- 计算器: 练习事件处理和逻辑运算。
- 简易博客: 实现文章的增删改查功能,数据可以暂时存在内存或
localStorage中。
学习建议:
- 动手敲代码: 不要只看不练,把教程中的例子都自己敲一遍,并尝试修改它们。
- 学会调试: 熟练使用浏览器开发者工具(特别是 Console 和 Sources 面板)。
- 阅读优秀代码: 去 GitHub 上看一些优秀的开源项目,学习别人的代码风格和实现方式。
- 保持耐心: JavaScript 是一门非常灵活且强大的语言,很多概念需要时间去消化,遇到困难是正常的,坚持下去就会豁然开朗。
祝你学习愉快!
