es6_quick_guide
ES6 - 快速指南
Section titled “ES6 - 快速指南”ES6 - 概览
Section titled “ES6 - 概览”ECMAScript (ES) 是由 ECMA International 标准化的脚本语言规范。它是 JavaScript 的基础。ES6,官方名称为 ECMAScript 2015,是一个重要的更新,为该语言引入了许多新特性,使 JavaScript 更加强大和富有表现力。随后的年度版本(ES2016、ES2017 等)继续添加特性。
本教程快速概述了关键的 ES6 特性及相关的现代 JavaScript 概念。
JavaScript 背景
Section titled “JavaScript 背景”JavaScript 于 1995 年由 Brendan Eich 在 Netscape 创建。它是一种高级的、通常采用即时编译(just-in-time compiled)的、多范式语言,遵循 ECMAScript 规范。它主要作为网页的脚本语言而闻名,但由于 Node.js,它也被用于许多非浏览器环境。
涵盖的关键 ES6 (ECMAScript 2015) 特性:
Section titled “涵盖的关键 ES6 (ECMAScript 2015) 特性:”- 常量 (
const) 和块级作用域变量 (let) - 箭头函数 (Arrow Functions)
- 默认参数值
- 剩余参数 (Rest Parameters) 和展开语法 (Spread Syntax)
- 模板字面量 (Template Literals)
- 增强的对象字面量(属性简写、方法定义)
- 解构赋值(数组和对象)
- 模块 (
import/export) - 类 (
class语法) - 迭代器 (Iterators) 和生成器 (Generators)(
function*,yield) - 集合(
Map,Set,WeakMap,WeakSet) - Promise(用于异步编程)
- 各种对象(String, Array, Number, Math, Object)的新内置方法
ES6 - 环境
Section titled “ES6 - 环境”要编写和运行 ES6+ JavaScript 代码,您有以下几种选择:
1. 现代 Web 浏览器
Section titled “1. 现代 Web 浏览器”所有现代 Web 浏览器(Chrome、Firefox、Safari、Edge)对 ES6 及更高版本特性都提供了出色的支持。您可以直接在 <script> 标签中或链接到 HTML 的 .js 文件中编写 ES6 代码。浏览器开发者工具(通常按 F12 访问)提供了一个控制台,用于试验 JavaScript 和调试您的代码。
2. Node.js
Section titled “2. Node.js”Node.js 是一个 JavaScript 运行时环境,允许您在浏览器之外运行 JavaScript 代码,通常用于服务器端应用程序、命令行工具和构建脚本。最新版本的 Node.js 对 ES6+ 特性提供了强大的支持。
安装 Node.js:
Section titled “安装 Node.js:”访问 Node.js 官方网站 (https://nodejs.org/) 下载适用于您操作系统的安装程序(Windows、macOS、Linux)。建议安装 LTS(长期支持)版本以获得稳定性。安装通常包含 npm(Node 包管理器),用于管理项目依赖和运行脚本。
安装完成后,您可以通过打开终端或命令提示符并输入以下命令来验证:
node -vnpm -v这将显示 Node.js 和 npm 的已安装版本。
3. 代码编辑器和 IDE
Section titled “3. 代码编辑器和 IDE”优秀的代码编辑器或集成开发环境 (IDE) 将显著提升您的开发体验,它们提供语法高亮、代码补全、调试工具和 Git 集成等功能。流行的 JavaScript 开发工具包括:
- Visual Studio Code (VS Code): 免费、开源、非常流行且功能丰富。提供出色的 JavaScript/TypeScript 支持和庞大的扩展市场。可在 https://code.visualstudio.com/ 获取。
- WebStorm: JetBrains 出品的一款强大的商业 IDE,专为 JavaScript 及相关技术设计。
- Sublime Text: 一款轻量、快速的编辑器,可通过插件扩展。
- Atom: GitHub 构建的可定制文本编辑器,免费且开源。
4. 转译器(用于旧环境)
Section titled “4. 转译器(用于旧环境)”如果您需要支持不完全支持 ES6+ 的旧浏览器或环境,可以使用转译器(transpiler),例如 Babel (https://babeljs.io/)。Babel 将现代 JavaScript 代码 (ES6+) 转换为更旧、兼容性更好的版本(例如 ES5)。这通常是构建过程的一部分,配合 Webpack、Parcel 或 Rollup 等工具使用。
ES6 - 语法
Section titled “ES6 - 语法”JavaScript 语法定义了编写有效程序的规则。主要组成部分包括:
- 变量 (Variables): 存储数据的命名容器。使用
let、const(ES6+) 或var(旧式) 声明。 - 字面量 (Literals): 直接写入代码的固定值(例如,
100、"hello"、true、null、[1, 2]、{a:1})。 - 运算符 (Operators): 对值执行操作的符号(例如,
+、-、*、/、=、===、&&、||)。 - 关键字 (Keywords): 具有特殊含义的保留字(例如,
if、for、function、class、return、let、const)。 - 注释 (Comments): 被解释器忽略,用于解释代码。单行注释(
// ...)和多行注释(/* ... */)。 - 标识符 (Identifiers): 变量、函数、类等的名称。规则:
- 必须以字母、下划线 (
_) 或美元符号 ($) 开头。 - 后续字符可以是字母、数字、下划线或美元符号。 - 区分大小写(例如,myVar和myvar是不同的)。 - 不能是保留关键字。 - 语句 (Statements): 要执行的指令。通常以分号 (
;) 结尾。 - 块 (Blocks): 用花括号 (
{}) 包围的语句组。
常用 JavaScript 关键字 (ES6+ 重点):
Section titled “常用 JavaScript 关键字 (ES6+ 重点):”break, case, catch, class, const, continue, debugger, default, delete, do, else, export, extends, false, finally, for, function, if, import, in, instanceof, let, new, null, return, super, switch, this, throw, true, try, typeof, var (legacy), void, while, with (discouraged), yield.
(Note: enum, implements, interface, package, private, protected, public, static are reserved for future use, though static is used within classes.)
JavaScript 在很大程度上忽略标记之间的空白(空格、制表符、换行),允许灵活的代码格式化。但是,在某些上下文中(例如,字符串字面量内部),空白可能很重要。
分号 (;) 用于终止语句。虽然 JavaScript 有自动插入分号 (ASI) 的机制,它会尝试在缺少分号的地方插入分号,但最佳实践是明确包含分号,以避免歧义和潜在错误。
console.log("Hello ES6");console.log("Multiple statements on one line require semicolons:"); let x = 5; let y = 10;严格模式 ("use strict";) 是一种选择加入 JavaScript 限制变体的方式。它有助于捕获常见的编码错误,并阻止某些不安全的操作或为其抛出错误。它可以应用于整个脚本或单个函数。
"use strict";
// 严格模式下的错误示例:// undeclaredVariable = "This would throw an error";
function strictFunction() { "use strict"; // 函数级严格模式 // anotherUndeclared = "Error here too";}
console.log("Strict mode is active globally in this example if at top of file.");注意:ES6 模块默认处于严格模式。
ES6 - 变量
Section titled “ES6 - 变量”变量是数据的命名存储。ES6 引入了 let 和 const 用于变量声明,与旧的 var 关键字相比,它们提供了更好的作用域和控制。
- 声明一个块级作用域的局部变量,可以选择性地初始化一个值。
- 块级作用域意味着变量只能在其定义的块 (
{...}) 内部访问(例如,在if语句、for循环或独立块内部)。 - 使用
let声明的变量不能在同一作用域内重复声明。 - 它们会被提升 (hoisted) 到其块的顶部,但在遇到声明之前不会初始化(临时死区 - Temporal Dead Zone - TDZ)。在声明之前访问它们会导致
ReferenceError。
let 示例:
Section titled “let 示例:”let count = 10;if (count > 5) { let message = "Greater than 5"; // 块级作用域 console.log(message);}// ReferenceError: message 在这里未定义// console.log(message);
count = 20; // 允许// SyntaxError: 标识符 'count' 已被声明// let count = 30;- 声明一个块级作用域的常量。
- 必须在声明时初始化。
- 初始化后其值不能被重新赋值。
- 与
let类似,const变量是块级作用域的,在声明之前处于 TDZ 中。 - 对于用
const声明的对象和数组,变量本身不能被重新赋值给新的对象/数组,但对象属性或数组元素可以被修改。
const 示例:
Section titled “const 示例:”const PI = 3.14159;// TypeError: 给常量变量赋值。// PI = 3.14;
const person = { name: "Alice", age: 30};person.age = 31; // 允许:修改对象的属性console.log(person);
// TypeError: 给常量变量赋值。// person = { name: "Bob" };var (传统方式)
Section titled “var (传统方式)”- 声明一个函数作用域或全局作用域的变量。
- 使用
var声明的变量会被提升 (hoisted) 到其函数或全局作用域的顶部,并初始化为undefined。 - 可以在同一作用域内重复声明而不会出错。
在现代 JavaScript 中,通常建议使用 let 和 const 来获得更清晰的作用域,并避免与 var 相关联的常见陷阱。
ES6 - 运算符
Section titled “ES6 - 运算符”运算符 (Operators) 是对操作数(值或变量)执行操作的符号。
算术运算符:
Section titled “算术运算符:”+ (加法), - (减法), * (乘法), / (除法), % (取模/余数), ** (指数运算符 - ES2016), ++ (自增), -- (自减)。
赋值运算符:
Section titled “赋值运算符:”= (赋值), +=, -=, *=, /=, %=, **=。
比较运算符:
Section titled “比较运算符:”== (等于,带类型强制转换), != (不等于,带类型强制转换), === (严格等于,不带类型强制转换), !== (严格不等于,不带类型强制转换), > (大于), < (小于), >= (大于或等于), <= (小于或等于)。始终优先使用 === 和 !==,而不是 == 和 !=,以避免由于类型强制转换导致的意外行为。
逻辑运算符:
Section titled “逻辑运算符:”&& (逻辑与), || (逻辑或), ! (逻辑非)。
& (与), | (或), ^ (异或), ~ (非), << (左移), >> (有符号右移), >>> (无符号右移)。
条件(三元)运算符:
Section titled “条件(三元)运算符:”condition ? exprIfTrue : exprIfFalse
类型运算符:
Section titled “类型运算符:”typeof (返回操作数的类型字符串), instanceof (检查对象是否是特定类或构造函数的实例)。
展开 (...) 和剩余 (...) 运算符 (ES6):
Section titled “展开 (...) 和剩余 (...) 运算符 (ES6):”-
- 展开语法 (Spread Syntax): 将可迭代对象(如数组或字符串)展开为单独的元素,或将对象展开为键值对。用于函数调用、数组字面量和对象字面量。
-
- 剩余参数 (Rest Parameter): 将不定数量的参数收集到一个数组中。用于函数参数列表。
展开和剩余参数示例:
Section titled “展开和剩余参数示例:”const arr1 = [1, 2, 3];const arr2 = [...arr1, 4, 5]; // 展开:[1, 2, 3, 4, 5]
function sum(...numbers) { // 剩余参数 return numbers.reduce((acc, current) => acc + current, 0);}console.log(sum(1, 2, 3, 4)); // 输出: 10ES6 - 决策
Section titled “ES6 - 决策”决策结构允许您的代码根据条件执行不同的语句块。
if 语句:
Section titled “if 语句:”如果指定的条件为真,则执行代码块。
if...else 语句:
Section titled “if...else 语句:”如果条件为真,则执行一个代码块;如果条件为假,则执行另一个代码块。
if...else if...else 语句:
Section titled “if...else if...else 语句:”顺序测试多个条件,并执行与第一个真条件对应的代码块。
let score = 85;if (score >= 90) { console.log("Grade: A");} else if (score >= 80) { console.log("Grade: B"); // 这将执行} else if (score >= 70) { console.log("Grade: C");} else { console.log("Grade: F");}switch 语句:
Section titled “switch 语句:”评估一个表达式,并将其值与一系列 case 子句进行匹配。执行与匹配的 case 相关联的语句。通常使用 break 语句退出 switch;否则,执行会继续“穿透”到后续的 case。
let day = "Monday";switch (day) { case "Saturday": case "Sunday": console.log("It's the weekend!"); break; case "Monday": console.log("Start of the work week."); break; default: console.log("It's a weekday.");}ES6 - 循环
Section titled “ES6 - 循环”循环用于重复执行代码块。
for 循环:
Section titled “for 循环:”重复执行代码块已知次数。包含初始化、条件和最终表达式(增量/减量)。
for (let i = 0; i < 5; i++) { console.log(`Iteration ${i}`);}while 循环:
Section titled “while 循环:”只要指定的条件为真,就重复执行代码块。在每次迭代之前检查条件。
do...while 循环:
Section titled “do...while 循环:”类似于 while,但在每次迭代 之后 检查条件,因此代码块总是至少执行一次。
for...in 循环:
Section titled “for...in 循环:”遍历对象的可枚举字符串属性(包括继承属性)。对于数组,它遍历索引。通常不建议用于遍历数组,如果顺序很重要或者您只想遍历自身的属性;对于数组,请改用 for...of 或像 forEach 这样的数组方法。
const person = { name: "John", age: 30 };for (const key in person) { if (person.hasOwnProperty(key)) { // 检查自身属性的最佳实践 console.log(`${key}: ${person[key]}`); }}for...of 循环 (ES6):
Section titled “for...of 循环 (ES6):”遍历可迭代对象(如 Array, String, Map, Set 等)的值。如果您需要直接获取值,这是遍历数组元素的优选方法。
const colors = ["red", "green", "blue"];for (const color of colors) { console.log(color);}循环控制语句:break(退出循环)和 continue(跳过当前迭代并继续下一次迭代)。
ES6 - 函数
Section titled “ES6 - 函数”函数是可重用代码块,用于执行特定任务。ES6 为函数引入了多项增强。
function greet(name) { console.log(`Hello, ${name}!`);}greet("World"); // Output: Hello, World!函数表达式:
Section titled “函数表达式:”const greet = function(name) { return `Hello, ${name}!`;};console.log(greet("World")); // Output: Hello, World!箭头函数 (Arrow Functions) (ES6):
Section titled “箭头函数 (Arrow Functions) (ES6):”提供了一种简洁的语法来编写函数表达式。它们词法绑定了 this 值,这意味着箭头函数内部的 this 指向其外部(封闭)词法作用域的 this 值。它们不适用于需要自己 this 上下文的方法(例如引用对象本身的成员方法)或构造函数。
- 基本形式:
(param1, param2) => { statements } - 单个参数(括号可选):
param => { statements } - 无参数:
() => { statements } - 单个表达式(隐式返回,省略花括号和
return关键字):(param1, param2) => expression
箭头函数示例:
Section titled “箭头函数示例:”const multiply = (x, y) => x * y;console.log(multiply(4, 5)); // 输出: 20
const square = num => num * num; // 单个参数时括号可选console.log(square(7)); // 输出: 49
const sayHi = () => console.log("Hi there!");sayHi(); // 输出: Hi there!
const numbers = [1, 2, 3, 4];const doubled = numbers.map(n => n * 2);console.log(doubled); // 输出: [2, 4, 6, 8]箭头函数中的词法 this:
Section titled “箭头函数中的词法 this:”function Timer() { this.seconds = 0; // 在传统函数中,setInterval 内部的 'this' 将是全局对象或 undefined (严格模式下) // setInterval(function() { // // 这里的 'this' 不是 Timer 实例 // this.seconds++; // console.log(this.seconds); // }, 1000);
// 箭头函数从 Timer 构造函数作用域继承 'this' setInterval(() => { this.seconds++; console.log(`Timer (lexical this): ${this.seconds}`); }, 1000);}// 在浏览器/Node 环境中取消注释运行此示例// const myTimer = new Timer();默认参数值 (Default Parameter Values) (ES6):
Section titled “默认参数值 (Default Parameter Values) (ES6):”您可以为函数参数指定默认值。如果未提供该参数的实参或实参为 undefined,则使用默认值。
默认参数示例:
Section titled “默认参数示例:”function greetUser(name = "Guest", message = "Welcome") { console.log(`${message}, ${name}!`);}greetUser(); // 输出: Welcome, Guest!greetUser("Alice"); // 输出: Welcome, Alice!greetUser("Bob", "Good morning"); // 输出: Good morning, Bob!剩余参数 (Rest Parameters) (ES6):
Section titled “剩余参数 (Rest Parameters) (ES6):”剩余参数语法 (...paramName) 允许函数接受不确定数量的参数并将其作为一个数组。它必须是函数定义中的最后一个参数。
剩余参数示例:
Section titled “剩余参数示例:”function sumAll(...numbers) { let total = 0; for (const num of numbers) { total += num; } return total;}console.log(sumAll(1, 2, 3)); // 输出: 6console.log(sumAll(10, 20, 30, 40, 50)); // 输出: 150console.log(sumAll()); // 输出: 0函数调用中的展开语法 (Spread Syntax) (...) (ES6):
Section titled “函数调用中的展开语法 (Spread Syntax) (...) (ES6):”展开语法允许将可迭代对象(如数组)在函数调用中展开为单个参数。
展开语法示例:
Section titled “展开语法示例:”function calculateProduct(a, b, c) { return a * b * c;}const values = [2, 3, 4];console.log(calculateProduct(...values)); // 相当于 calculateProduct(2, 3, 4) -> 输出: 24Generator Functions (ES6): 详见专门章节。
ES6 - 事件
Section titled “ES6 - 事件”事件是浏览器中发生的动作或情况,例如用户点击按钮、页面加载完成或按下按键。JavaScript 允许您响应这些事件。
现代且推荐的事件处理方式是使用 addEventListener() 方法。这允许您为同一事件类型向一个元素附加多个事件处理程序。
语法: element.addEventListener(type, listener, options?)
type: 表示事件类型的字符串(例如,"click"、"mouseover"、"keydown")。listener: 当事件发生时要调用的函数(事件处理程序)。它接收一个Event对象作为参数。options(可选): 包含选项的对象,例如capture(boolean)、once(boolean)、passive(boolean)。
addEventListener 示例:
Section titled “addEventListener 示例:”<!DOCTYPE html><html><head><title>Event Example</title></head><body> <button id="myButton">Click Me</button> <p id="message"></p> <script> const button = document.getElementById('myButton'); const messagePara = document.getElementById('message');
button.addEventListener('click', function(event) { messagePara.textContent = 'Button clicked! Event type: ' + event.type; console.log('Event object:', event); });
button.addEventListener('mouseover', () => { button.style.backgroundColor = 'lightblue'; });
button.addEventListener('mouseout', () => { button.style.backgroundColor = ''; // Reset background }); </script></body></html>常见事件类型:
Section titled “常见事件类型:”- 鼠标事件 (Mouse Events):
click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave。 - 键盘事件 (Keyboard Events):
keydown,keyup,keypress(传统方式,如果可能请避免使用)。 - 表单事件 (Form Events):
submit,reset,change(用于输入字段、选择框、文本区域),input,focus,blur。 - 文档/窗口事件 (Document/Window Events):
load,unload,DOMContentLoaded,resize,scroll。
传统事件处理(新代码中避免使用):
Section titled “传统事件处理(新代码中避免使用):”-
HTML on-event 属性:
<button onclick="myFunction()">。这混合了 HTML 和 JavaScript,使代码更难维护。 -
DOM 元素 on-event 属性:
element.onclick = myFunction;。这只允许每种事件类型有一个处理程序。
当事件发生时,一个 Event 对象(或更具体的类型,如 MouseEvent、KeyboardEvent)会被传递给事件处理程序函数。该对象包含有关事件的信息,例如:
type: 事件的类型。target: 触发事件的 DOM 元素。currentTarget: 附加事件处理程序的 DOM 元素。preventDefault(): 取消浏览器对该事件的默认操作的方法(例如,阻止表单提交)。stopPropagation(): 阻止事件在 DOM 树中冒泡或捕获的方法。
有关 HTML5 标准事件列表,请参阅 MDN:https://developer.mozilla.org/en-US/docs/Web/Events
ES6 - Cookies
Section titled “ES6 - Cookies”Cookie 是由用户的网络浏览器存储在用户计算机上的小型文本文件,用于跨会话记住有关用户的信息。JavaScript 可以使用 document.cookie 与 Cookie 交互。
关键操作:
- 设置/更新:
document.cookie = "name=value; expires=UTCString; path=/; SameSite=Lax"; - 读取:
document.cookie返回所有 Cookie 的字符串;您需要解析它。 - 删除: 将
expires属性设置为一个过去日期。
重要:对 Cookie 值始终使用 encodeURIComponent(),读取时使用 decodeURIComponent()。出于安全考虑,考虑 HttpOnly、Secure 和 SameSite 属性(通常在服务器端设置)。对于不需要服务器交互的客户端存储,localStorage 和 sessionStorage 通常是更好的替代方案。
详见专门的“ES6 - Cookies”章节以获取详细示例和最佳实践。
ES6 - 页面重定向
Section titled “ES6 - 页面重定向”JavaScript 可以使用 window.location 对象将浏览器重定向到新的 URL。
window.location.href = "new_url";(导航并添加到历史记录)window.location.assign("new_url");(与上述相同)window.location.replace("new_url");(导航但替换历史记录中的当前条目,后退按钮不会返回到原始页面)window.location.reload();(重新加载当前页面)
对于 SEO,服务器端重定向(永久重定向使用 301)通常优于 JavaScript 重定向。
详见专门的“ES6 - 页面重定向”章节以获取更多详细信息。
ES6 - 对话框
Section titled “ES6 - 对话框”JavaScript 提供了内置函数,通过对话框进行简单的用户交互。尽管它们功能可用,但它们是模态的(阻塞用户与页面其余部分的交互),并且外观通常比较过时。现代 Web 应用程序通常使用自定义风格的模态框或通知。
alert(message):
Section titled “alert(message):”显示带有一个“确定”按钮的简单消息。
confirm(message):
Section titled “confirm(message):”显示带有一个“确定”按钮和一个“取消”按钮的消息。如果点击“确定”返回 true,如果点击“取消”返回 false。
prompt(message, defaultValue?):
Section titled “prompt(message, defaultValue?):”显示消息询问用户输入,带有一个输入字段。如果点击“确定”返回输入的字符串,如果点击“取消”返回 null。defaultValue 是输入字段的可选初始值。
alert("This is an alert!");
const wantsToContinue = confirm("Do you want to continue?");if (wantsToContinue) { console.log("User wants to continue.");} else { console.log("User does not want to continue.");}
const userName = prompt("Please enter your name:", "John Doe");if (userName !== null) { console.log(`Hello, ${userName}`);} else { console.log("User cancelled the prompt.");}ES6 - void 关键字
Section titled “ES6 - void 关键字”void 运算符评估一个表达式然后返回 undefined。它在过去的主要用途是与 javascript: URL 结合使用,以防止当表达式的返回值可能导致浏览器离开当前页面时进行导航。
语法: void expression 或 void(expression)
<a href="javascript:void(0);">Do nothing link</a><a href="javascript:void(console.log('Clicked!'));">Log and do nothing link</a>在现代 JavaScript 中,void 0 有时被用作获取 undefined 值的简洁方式。然而,简单地使用 undefined 基本类型通常更清晰。随着现代事件处理(例如,event.preventDefault())的出现,javascript:void(0) 在链接中的需求已经减少。
ES6 - 页面打印
Section titled “ES6 - 页面打印”JavaScript 可以使用 window.print() 方法触发浏览器的打印对话框。这将尝试打印当前文档。
<!DOCTYPE html><html><head><title>Print Example</title></head><body> <p>This is some content to print.</p> <button onclick="window.print()">Print this page</button></body></html>您可以使用 CSS 媒体查询 (@media print) 为页面的打印版本定义特定的样式,使其与屏幕版本不同。
ES6 - 对象
Section titled “ES6 - 对象”对象是键值对(属性)的集合。ES6 引入了多项增强功能以处理对象。
对象字面量增强:
Section titled “对象字面量增强:”- 属性简写 (Shorthand Property Names): 如果变量名与属性键相同,您可以省略冒号和值:
let name = "Alice"; let person = { name };等同于let person = { name: name }; - 方法简写 (Shorthand Method Names):
let person = { greet() { console.log("Hello"); } };代替let person = { greet: function() { console.log("Hello"); } }; - 计算属性名 (Computed Property Names): 在对象字面量中使用方括号内的表达式作为属性键:
let propName = "age"; let person = { [propName]: 30 };
Object.assign(target, ...sources):
Section titled “Object.assign(target, ...sources):”将一个或多个源对象中所有可枚举的自身属性复制到目标对象(浅拷贝)。用于合并对象或克隆。
对象解构 (Object Destructuring):详见专门章节。
详见专门的“ES6 - 对象”章节以获取更多详细信息和示例。
ES6 - Number
Section titled “ES6 - Number”ES6 为 Number 对象添加了新的属性和方法。
Number.EPSILON: 两个可表示数字之间最小的间隔。Number.isFinite(value): 检查值是否为有限数字。Number.isInteger(value): 检查值是否为整数。Number.isNaN(value): 检查值是否为NaN(比全局isNaN()更健壮)。Number.isSafeInteger(value): 检查值是否为安全整数(可以精确表示为 IEEE-754 双精度数)。Number.parseFloat(string)和Number.parseInt(string, radix): 全局函数也可在Number对象上使用。
二进制和八进制字面量 (ES6):
Section titled “二进制和八进制字面量 (ES6):”二进制数使用前缀 0b 或 0B(例如,0b1010 是 10)。
八进制数使用前缀 0o 或 0O(例如,0o12 是 10)。
ES6 - Boolean
Section titled “ES6 - Boolean”Boolean 对象表示真假值:true 或 false。JavaScript 中隐式为假(falsy 值)的值包括 false、0、-0、0n (BigInt 零)、"" (空字符串)、null、undefined 和 NaN。所有其他值都是真值 (truthy)。
ES6 - Strings
Section titled “ES6 - Strings”字符串表示文本数据。ES6 引入了模板字面量和新的字符串方法。
模板字面量 (Template Literals): Hello, ${name}! 用于轻松实现字符串插值和多行字符串。
新方法:startsWith()、endsWith()、includes()、repeat()。
详见专门的“ES6 - Strings”和“ES6 - 新字符串方法”章节。
ES6 - Arrays
Section titled “ES6 - Arrays”数组是有序的值集合。ES6 为数组添加了许多有用的方法和特性。
新的静态方法:
Section titled “新的静态方法:”Array.from(arrayLikeOrIterable, mapFn?, thisArg?): 从类数组对象或可迭代对象创建一个新的 Array 实例。Array.of(...elements): 创建一个新的 Array 实例,参数数量可变,无论参数的数量或类型如何。
新的实例方法:
Section titled “新的实例方法:”find(callbackFn, thisArg?): 返回满足所提供测试函数的第一个元素。findIndex(callbackFn, thisArg?): 返回满足所提供测试函数的第一个元素的索引。fill(value, start?, end?): 用静态值填充数组从开始索引到结束索引之间的所有元素。copyWithin(target, start?, end?): 将数组的一部分浅拷贝到同一数组中的另一个位置。entries(): 返回一个新的 Array 迭代器对象,其中包含每个索引的键/值对。keys(): 返回一个新的 Array 迭代器对象,其中包含每个索引的键(索引)。values(): 返回一个新的 Array 迭代器对象,其中包含每个索引的值。
展开语法 (...) 和解构:与数组一起使用也非常有用。
ES6 - Date
Section titled “ES6 - Date”Date 对象用于处理日期和时间。它的 API 在 ES6 中基本没有变化,但对于日期操作很重要。由于原生 Date 对象处理时区和格式化比较复杂,现代 JavaScript 通常使用 date-fns 或 Luxon 等库来提供更健壮和开发人员友好的日期/时间处理能力。
ES6 - Math
Section titled “ES6 - Math”Math 对象提供了数学常数和函数的属性和方法。ES6 添加了几个新的辅助方法:
Math.trunc(x): 通过移除小数部分返回 x 的整数部分。Math.sign(x): 返回 x 的符号(正数返回 1,负数返回 -1,零返回 0)。Math.cbrt(x): 返回 x 的立方根。Math.log2(x): 返回 x 的以 2 为底的对数。Math.log10(x): 返回 x 的以 10 为底的对数。Math.log1p(x): 返回 1 + x 的自然对数。Math.expm1(x): 返回 e^x - 1。Math.cosh(x),Math.sinh(x),Math.tanh(x),Math.acosh(x),Math.asinh(x),Math.atanh(x): 双曲函数。Math.hypot(...values): 返回其参数的平方和的平方根。Math.clz32(x): 返回 x 的 32 位二进制表示中前导零的个数。
ES6 - RegExp (Regular Expressions)
Section titled “ES6 - RegExp (Regular Expressions)”正则表达式 (RegExp) 是用于在字符串中匹配字符组合的模式。ES6 引入了新的标志和特性:
y(sticky) 标志: 只从 RegExp 对象的lastIndex属性指示的索引开始匹配。匹配必须从lastIndex开始。u(unicode) 标志: 启用更全面的 Unicode 支持,包括正确匹配基本多文种平面 (BMP) 之外的字符以及处理 Unicode 属性转义序列(\p{...})。- RegExp 构造函数可以接受另一个 RegExp 对象作为参数:
new RegExp(/abc/ig, 'i')创建一个具有可能不同标志的新 RegExp 对象。
ES6 - HTML DOM
Section titled “ES6 - HTML DOM”文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口。它将页面结构表示为对象树,允许 JavaScript 动态访问和更新网页的内容、结构和样式。
关键 DOM 概念:
Section titled “关键 DOM 概念:”- 节点 (Nodes): HTML 文档中的一切都是一个节点(元素节点、文本节点、属性节点、注释节点)。
document对象: DOM 的入口点,表示整个 HTML 文档。- 选择元素:
-
document.getElementById('id')-document.getElementsByTagName('tagname')(返回 HTMLCollection) -document.getElementsByClassName('classname')(返回 HTMLCollection) -document.querySelector('cssSelector')(返回第一个匹配的元素) -document.querySelectorAll('cssSelector')(返回所有匹配元素的 NodeList) - 操作元素:
- 读取/修改内容:
element.innerHTML、element.textContent、element.value(用于表单元素)。 - 修改属性:element.getAttribute()、element.setAttribute()、element.removeAttribute()、直接属性访问(例如,element.id、element.className)。 - 修改样式:element.style.property(例如,element.style.color = 'blue')、element.classList(add、remove、toggle、contains)。 - 创建和添加元素:
-
document.createElement('tagname')-parentNode.appendChild(newNode)-parentNode.insertBefore(newNode, referenceNode)-element.remove()(ES6+) - 遍历 DOM:
parentNode、childNodes、firstChild、lastChild、nextSibling、previousSibling、parentElement、children、firstElementChild、lastElementChild、nextElementSibling、previousElementSibling。
加载页面后,避免使用过时的方法(如 document.write())来修改内容。
ES6 - 集合
Section titled “ES6 - 集合”ES6 引入了新的内置可迭代数据结构:Map、Set、WeakMap 和 WeakSet。
有序的键值对集合。键可以是任何值(包括对象和基本类型)。方法:set(key, value)、get(key)、has(key)、delete(key)、clear()、size 属性。可通过 keys()、values()、entries() 进行迭代。
有序的唯一值集合。值可以是任何类型。方法:add(value)、has(value)、delete(value)、clear()、size 属性。可通过 keys()、values()、entries() 进行迭代(对于 Set,键和值相同)。
WeakMap 和 WeakSet:
Section titled “WeakMap 和 WeakSet:”特殊版本,其中键(对于 WeakMap)或值(对于 WeakSet)必须是对象。它们持有“弱”引用,这意味着如果一个对象键/值是仅剩的引用,它可以被垃圾回收。它们不可迭代,也没有 size 属性。用于将数据与对象关联,而不会阻止其垃圾回收。
ES6 - 类
Section titled “ES6 - 类”ES6 引入了 class 语法,它主要是 JavaScript 现有基于原型的继承的语法糖。它提供了一种更清晰、更熟悉的方式来创建对象和实现继承。
class关键字:class MyClass { ... }constructor方法: 用于创建和初始化类创建的对象的特殊方法。一个类只能有一个构造函数。- 方法 (Methods): 在类中定义的函数。
static方法: 在类本身上调用,而不是在实例上调用。static myStaticMethod() { ... }extends关键字: 用于继承。class ChildClass extends ParentClass { ... }super关键字: 用于调用父类的构造函数(super())或方法(super.parentMethod())。- Getter 和 Setter:
get myProp() { ... },set myProp(value) { ... }
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} barks.`); }}
const myDog = new Dog("Rex", "German Shepherd");myDog.speak();// 输出:// Rex makes a noise.// Rex barks.ES6 - Promises
Section titled “ES6 - Promises”Promise 是代表异步操作最终完成(或失败)及其结果值的对象。与传统的回调函数相比,它们提供了一种更清晰的方式来处理异步代码,避免了“回调地狱”。
Promise 可以处于以下三种状态之一:
Section titled “Promise 可以处于以下三种状态之一:”- Pending (挂起): 初始状态,既未完成也未拒绝。
- Fulfilled (已完成/已解决): 操作成功完成,带有结果值。
- Rejected (已拒绝): 操作失败,带有原因(错误)。
创建 Promise:
Section titled “创建 Promise:”const myPromise = new Promise((resolve, reject) => { // 异步操作 setTimeout(() => { const success = true; // 或 false if (success) { resolve("Operation successful!"); } else { reject(new Error("Operation failed.")); } }, 1000);});消费 Promise:
Section titled “消费 Promise:”使用 .then() 处理完成,.catch() 处理拒绝,.finally() 处理无论结果如何都会运行的代码。
myPromise .then(result => { console.log("Success:", result); }) .catch(error => { console.error("Error:", error.message); }) .finally(() => { console.log("Promise settled."); });async/await (ES2017):
Section titled “async/await (ES2017):”async 函数和 await 关键字构建在 Promise 之上,提供了一种看起来更像同步的方式来编写异步代码。
async function fetchData() { try { console.log("Fetching data..."); const result = await myPromise; // 暂停执行直到 myPromise 完成 console.log("Data received:", result); return result; } catch (error) { console.error("Fetch error:", error.message); throw error; // 如果需要则重新抛出 }}
fetchData().then(data => console.log("Final result from async function:", data));ES6 - 模块
Section titled “ES6 - 模块”ES6 引入了 JavaScript 的标准化模块系统,允许将代码组织成可重用的部分。模块有助于管理依赖关系并创建更易于维护的应用程序。
导出 (Exporting): 使用 export 关键字使函数、变量或类可以从模块中被访问。
export const PI = 3.14159;export function greet(name) { return `Hello, ${name}`;}export default function multiply(a, b) { // 默认导出 return a * b;}导入 (Importing): 使用 import 关键字在另一个模块中使用导出的成员。
import multiply, { PI, greet } from './lib.js'; // 先默认导入,然后命名导入// import * as utils from './lib.js'; // 以命名空间方式导入所有内容
console.log(PI); // 3.14159console.log(greet("ES6 Modules")); // Hello, ES6 Modulesconsole.log(multiply(5, 2)); // 10ES6 模块通常通过 <script type="module" src="..."></script> 在浏览器中使用。Node.js 也支持 ES 模块(通常需要 .mjs 扩展名或特定的 package.json 配置)。对于旧环境,Babel 等转译器会将 ES 模块转换为其他格式(如 CommonJS 或 AMD)。
ES6 - 错误处理
Section titled “ES6 - 错误处理”适当的错误处理对于健壮的应用程序至关重要。JavaScript 使用 try...catch...finally 块进行同步错误处理,而 Promise 具有内置机制(.catch(),async/await 结合 try/catch)处理异步错误。
try...catch 语句:
Section titled “try...catch 语句:”try 块包含可能抛出错误的代码。如果发生错误,将执行 catch 块,并带有一个错误对象。finally 块(可选)无论是否发生错误都会执行。
try { let result = riskyOperation(); console.log(result);} catch (error) { console.error("An error occurred:", error.name, error.message); // error.stack 对于调试也很有用} finally { console.log("Cleanup code runs here.");}throw 语句:用于创建和抛出自定义错误或重新抛出现有错误。throw new Error("Something went wrong");
错误对象:标准内置错误类型包括 Error, SyntaxError, TypeError, RangeError, ReferenceError, URIError。您可以通过扩展 Error 创建自定义错误类。
详见专门的“ES6 - 错误处理”章节以获取更多详细信息。
ES6 - 验证
Section titled “ES6 - 验证”表单验证确保用户输入在处理或提交之前是正确、完整且格式正确的。验证可以发生在客户端(在浏览器中使用 JavaScript)和/或服务器端。
客户端验证的好处:
Section titled “客户端验证的好处:”- 改善用户体验: 为用户提供即时反馈,减少沮丧感。
- 减少服务器负载: 防止因无效数据而产生不必要的请求。
客户端验证的技术:
Section titled “客户端验证的技术:”- HTML5 内置验证: 在表单元素上使用
required、type(例如,email、number、url)、pattern(用于正则表达式)、min、max、minlength、maxlength等属性。浏览器会处理基本验证并提供默认错误消息。 - JavaScript 验证: 用于更复杂或自定义的验证逻辑。访问表单字段值,根据规则检查它们,并显示自定义错误消息。通常与 HTML5 验证结合使用。
示例(JavaScript 验证):
Section titled “示例(JavaScript 验证):”<!DOCTYPE html><html><head><title>Validation</title></head><body> <form id="myForm"> <label for="email">Email:</label> <input type="text" id="email" name="email"> <span id="emailError" style="color:red;"></span><br><br> <button type="submit">Submit</button> </form> <script> const form = document.getElementById('myForm'); const emailInput = document.getElementById('email'); const emailError = document.getElementById('emailError');
form.addEventListener('submit', function(event) { event.preventDefault(); // 阻止默认的表单提交 validateEmail(); });
function validateEmail() { const emailValue = emailInput.value.trim(); if (emailValue === '') { emailError.textContent = 'Email is required.'; return false; } else if (!/^\S+@\S+\.\S+$/.test(emailValue)) { // 简单的邮箱正则表达式 emailError.textContent = 'Please enter a valid email address.'; return false; } emailError.textContent = ''; // 清除错误 // 如果有效,您可以继续表单提交(例如,使用 Fetch API) console.log('Form submitted with email:', emailValue); return true; } </script></body></html>重要: 始终也实现服务器端验证,因为客户端验证可以被绕过。
ES6 - 动画
Section titled “ES6 - 动画”JavaScript 可以通过随时间动态改变元素的属性(如位置、大小、颜色、不透明度)来创建网页上的动画。
requestAnimationFrame(callback):
Section titled “requestAnimationFrame(callback):”这是在 JavaScript 中创建平滑高效动画的现代、推荐方式。浏览器在下一次屏幕重绘之前(通常每秒 60 次)调用您的 callback 函数。这使得动画与浏览器的刷新率同步,与使用 setTimeout 或 setInterval 进行动画相比,性能更好,卡顿更少。
requestAnimationFrame 移动元素的示例:
Section titled “requestAnimationFrame 移动元素的示例:”<!DOCTYPE html><html><head><title>Animation</title><style> #box { width: 50px; height: 50px; background-color: blue; position: relative; } </style></head><body> <div id="box"></div> <script> const box = document.getElementById('box'); let position = 0; let startTime = null;
function animate(timestamp) { if (!startTime) startTime = timestamp; const progress = timestamp - startTime;
position += 1; // 每帧移动 1 像素 if (position > 300) position = 0; // 重置位置 box.style.left = position + 'px';
if (progress < 5000) { // 运行动画约 5 秒 requestAnimationFrame(animate); } } requestAnimationFrame(animate); // 启动动画 </script></body></html>使用 setTimeout / setInterval 的传统动画(旧代码):
Section titled “使用 setTimeout / setInterval 的传统动画(旧代码):”虽然可能,但使用 setTimeout 或 setInterval 进行动画可能导致卡顿和效率低下,因为它们与浏览器的重绘周期不同步。requestAnimationFrame 通常更优越。
CSS 动画和过渡:
Section titled “CSS 动画和过渡:”对于许多常见的动画(例如,悬停效果、状态之间的过渡),CSS 动画和 CSS 过渡通常是更好的选择。浏览器可以优化它们,因此它们通常性能更好,并且将表现逻辑与 JavaScript 分离。
ES6 - 多媒体
Section titled “ES6 - 多媒体”现代 Web 浏览器主要通过 HTML5 的 <audio> 和 <video> 元素支持多媒体内容。JavaScript 提供了 API 来控制这些元素。
HTML5 <audio> 和 <video> 元素:
Section titled “HTML5 <audio> 和 <video> 元素:”这些元素允许您直接将音频和视频内容嵌入到网页中。它们具有 src、controls、autoplay、loop、muted、poster(用于视频)等属性。
HTML 示例:
Section titled “HTML 示例:”<video id="myVideo" width="320" height="240" controls> <source src="movie.mp4" type="video/mp4"> <source src="movie.ogg" type="video/ogg"> 您的浏览器不支持 video 标签。</video>
<audio id="myAudio" controls> <source src="sound.mp3" type="audio/mpeg"> <source src="sound.ogg" type="audio/ogg"> 您的浏览器不支持 audio 元素。</audio>JavaScript 媒体 API:
Section titled “JavaScript 媒体 API:”您可以使用音频/视频 DOM 元素上的 JavaScript 方法和属性来控制播放、音量、音轨选择等:
- 方法:
play()、pause()、load()。 - 属性:
currentTime、duration、volume、muted、paused、ended、src。 - 事件:
play、pause、ended、timeupdate、volumechange、canplay、error。
示例(控制视频):
Section titled “示例(控制视频):”<!DOCTYPE html><html><head><title>Media Control</title></head><body> <video id="sampleVideo" width="320" height="240" src="your_video.mp4"></video><br> <button onclick="document.getElementById('sampleVideo').play()">Play</button> <button onclick="document.getElementById('sampleVideo').pause()">Pause</button> <input type="range" min="0" max="1" step="0.1" value="1" oninput="document.getElementById('sampleVideo').volume = this.value"> 音量</body></html>之前用于检测浏览器插件(如 Flash)的 navigator.plugins 和 navigator.mimeTypes 对象已基本过时,因为现代 Web 依赖于浏览器内置的多媒体功能。
ES6 - 调试
Section titled “ES6 - 调试”调试是查找和修复代码中错误(bug)的过程。现代浏览器和 Node.js 提供了强大的调试工具。
浏览器开发者工具:
Section titled “浏览器开发者工具:”所有主流浏览器都包含开发者工具(通常按 F12 或右键点击 -> 检查 打开)。JavaScript 调试的主要功能:
- 控制台 (Console): 查看
console.log()消息、错误和警告。交互式执行 JavaScript 表达式。 - 调试器/源文件面板 (Debugger/Sources Panel): 在代码中设置断点以暂停执行。逐行单步执行代码(
step over、step into、step out)。检查变量值、调用堆栈和作用域链。 - 网络面板 (Network Panel): 检查网络请求和响应。
- 性能面板 (Performance Panel): 分析 JavaScript 执行以识别瓶颈。
console 对象方法:
Section titled “console 对象方法:”console.log(...data): 常规输出。console.error(...data): 输出错误消息。console.warn(...data): 输出警告消息。console.info(...data): 输出信息性消息。console.table(data): 将表格数据以表格形式显示。console.group(label)/console.groupEnd(): 分组相关的日志消息。console.time(label)/console.timeEnd(label): 测量执行时间。
debugger; 语句:
Section titled “debugger; 语句:”在代码中放置 debugger; 语句将像一个断点一样工作,如果开发者工具打开,会在该行暂停执行。
Node.js 调试:
Section titled “Node.js 调试:”- 内置调试器:
node inspect myscript.js(或node --inspect myscript.js用于集成 Chrome DevTools)。 - IDE 调试器: VS Code 和其他 IDE 针对 Node.js 应用程序提供了出色的内置调试器。
通用调试技巧:
Section titled “通用调试技巧:”- 理解错误: 仔细阅读错误消息;它们通常指向问题的发生位置和类型。
- 持续复现 bug: 确定触发 bug 的步骤。
- 隔离问题: 简化代码或注释掉部分代码,以缩小 bug 发生的范围。
- 策略性地使用
console.log: 在不同阶段打印变量值,以了解代码流程和状态。 - 使用断点和单步执行代码: 详细观察执行流程和变量变化。
ES6 - 图像映射
Section titled “ES6 - 图像映射”客户端图像映射允许您在图像中定义可点击区域(热点),其中每个区域可以链接到不同的 URL 或触发 JavaScript 函数。
HTML 结构:
Section titled “HTML 结构:”<img usemap="#mapname">:<img>标签包含usemap属性,指向<map>元素的name。<map name="mapname">: 此元素包含可点击区域的定义。<area shape="rect|circle|poly" coords="..." href="url" alt="text">: 定义一个可点击区域。 -shape:rect(矩形),circle(圆形), 或poly(多边形)。 -coords: 定义形状的坐标。(例如,x1,y1,x2,y2用于rect;x,y,radius用于circle;x1,y1,x2,y2,...,xn,yn用于poly)。 -href: 要导航到的 URL。 -alt: 区域的替代文本。
与 JavaScript 集成:
Section titled “与 JavaScript 集成:”您可以将 JavaScript 事件处理程序(如 onclick、onmouseover)附加到 <area> 元素上,以便执行操作,而不是或除了导航到 URL 之外。
<!DOCTYPE html><html><head><title>Image Map</title><script> function showRegion(regionName) { document.getElementById('regionInfo').textContent = '您悬停在:' + regionName; } function clearRegion() { document.getElementById('regionInfo').textContent = ''; }</script></head><body> <img src="your-image.jpg" alt="Sample Image Map" usemap="#samplemap" width="300" height="200"> <map name="samplemap"> <area shape="rect" coords="0,0,100,100" href="#" alt="Top-Left Quadrant" onmouseover="showRegion('Top-Left Quadrant')" onmouseout="clearRegion()" onclick="alert('Clicked Top-Left'); return false;"> <area shape="circle" coords="200,100,50" href="#" alt="Center-Right Circle" onmouseover="showRegion('Center-Right Circle')" onmouseout="clearRegion()" onclick="alert('Clicked Center-Right'); return false;"> </map> <p id="regionInfo"></p></body></html>虽然仍然受支持,但如今图像映射在复杂 UI 中不太常见。CSS 技术、SVG 或基于 JavaScript 的 Canvas 命中检测可能为交互式图形提供更大的灵活性。然而,对于静态图像上简单的链接区域,它们仍然是一个有效的选择。
ES6 - 浏览器
Section titled “ES6 - 浏览器”理解浏览器环境对于 Web 开发非常重要。JavaScript 中的 navigator 对象提供了有关浏览器及其能力的信息。
navigator 对象属性:
Section titled “navigator 对象属性:”navigator.userAgent: 一个字符串,包含浏览器发送到服务器的用户代理头部信息。此字符串通常包括浏览器名称、版本、操作系统和渲染引擎详细信息。注意: 通常不鼓励使用用户代理嗅探来进行特性检测,因为它不可靠且难以维护。优先使用特性检测。navigator.language/navigator.languages: 关于用户首选语言的信息。navigator.platform: (已废弃) 表示浏览器运行平台的字符串(例如,“Win32”,“MacIntel”)。navigator.cookieEnabled: 一个布尔值,指示浏览器中是否启用 Cookie。navigator.onLine: 一个布尔值,指示浏览器当前是否具有网络连接。
navigator 对象方法:
Section titled “navigator 对象方法:”navigator.javaEnabled(): (已基本过时) 检查 Java(不是 JavaScript)是否启用。navigator.sendBeacon(url, data?): 将少量 HTTP 数据从浏览器异步传输到 Web 服务器,对于分析或诊断非常有用,且不会延迟页面卸载。
特性检测 (Feature Detection) vs. 浏览器嗅探 (Browser Sniffing):
Section titled “特性检测 (Feature Detection) vs. 浏览器嗅探 (Browser Sniffing):”与其尝试识别特定浏览器(navigator.userAgent 嗅探),几乎总是最好检测您想要使用的特定特性是否受支持。
示例(特性检测):
Section titled “示例(特性检测):”if (typeof Promise !== "undefined") { console.log("支持 Promise。");} else { console.log("不支持 Promise。请考虑使用 polyfill。");}
if ('geolocation' in navigator) { console.log("Geolocation API 可用。"); navigator.geolocation.getCurrentPosition(pos => console.log(pos.coords));} else { console.log("Geolocation API 不可用。");}现代浏览器高度符合标准,减少了对大量特定浏览器代码的需求。然而,理解浏览器差异对于性能优化、处理特定浏览器 bug 或使用非常新的特性仍然很重要。