JavaScript 入门实战:从核心语法到 DOM 交互的快速上手指南

📅 2026/8/6 9:01:58
JavaScript 入门实战:从核心语法到 DOM 交互的快速上手指南
JavaScript 作为现代 Web 开发的基石其重要性不言而喻。对于初学者而言面对海量的教程和复杂的概念往往不知从何下手容易陷入“一看就会一写就废”的困境。本文旨在为编程新手提供一个结构清晰、重点突出、可立即动手实践的 JavaScript 入门路径。我们将绕过冗长的理论铺垫直接切入核心语法和常用 API并通过一系列可运行的微型实战案例帮助你快速建立对 JavaScript 的直观理解掌握从变量声明到 DOM 操作、事件处理的基础技能。阅读本文你将能独立完成一个具备基础交互功能的网页小项目。1. 理解 JavaScript 的核心它是什么以及如何工作在开始写代码之前我们需要先理解 JavaScript 在 Web 开发中的角色。它不是一门孤立存在的语言而是与 HTML、CSS 共同构成了网页的“三驾马车”。1.1 JavaScript 的定位与作用通俗地讲如果把一个网页比作一个人HTML是人的骨骼和结构定义了标题、段落、图片、按钮等元素。CSS是人的皮肤和衣服负责颜色、字体、布局等外观样式。JavaScript则是人的肌肉和神经赋予了网页动态行为和交互能力。它的核心作用包括动态修改内容无需重新加载页面即可更新网页上的文字、图片。响应用户操作处理点击、鼠标移动、键盘输入等事件。控制浏览器操作浏览器窗口、历史记录进行本地数据存储。与服务器通信异步获取或提交数据即 AJAX 和 Fetch API。1.2 JavaScript 的运行环境JavaScript 代码需要一个“解释器”来执行。对于前端开发最常见的解释器就是浏览器内核中的 JavaScript 引擎如 Chrome 的 V8 Firefox 的 SpiderMonkey。这意味着你写的 JS 代码最终是在用户的浏览器中运行的。为了学习和测试我们通常有两种方式运行 JS 代码在浏览器中运行这是最主要的方式。我们可以将 JS 代码写在 HTML 文件的script标签内或引入外部的.js文件。在 Node.js 环境中运行Node.js 是一个让 JavaScript 可以脱离浏览器在服务器端运行的环境。对于初学者我们可以用它来快速测试一些纯逻辑的代码片段而不必每次都创建 HTML 文件。本文将主要使用浏览器环境因为这是前端 JavaScript 最天然的应用场景。1.3 准备你的开发环境你不需要安装复杂的 IDE 来开始学习。现代浏览器自带强大的开发者工具就是最好的学习环境。文本编辑器选择一款你顺手的即可如 VS Code、Sublime Text、甚至系统的记事本。推荐 VS Code因为它对前端开发支持非常友好有丰富的插件。浏览器Chrome 或 Firefox它们拥有功能完善的开发者工具。创建一个项目文件夹在电脑上新建一个文件夹例如js-quick-start。在这个文件夹里我们将创建所有练习文件。2. 从零开始JavaScript 基础语法速览我们将快速过一遍最核心的语法点。请记住学习编程语言动手敲代码比单纯阅读重要十倍。2.1 变量与常量数据的容器程序需要存储信息变量和常量就是用来存储数据的“盒子”。// 1. 使用 let 声明变量值可以改变 let userName 张三; let userAge 25; userAge 26; // 正确变量可以被重新赋值 console.log(userName, userAge); // 在控制台输出张三 26 // 2. 使用 const 声明常量值不可改变 const PI 3.14159; // PI 3.14; // 错误常量一旦声明其值就不能再被修改。 // 3. 已废弃的 var (了解即可现代开发中建议使用 let 和 const) var oldWay 不推荐;关键解释let用于声明可变的数据。const用于声明不可变的数据如配置项、数学常数。使用const可以提高代码的可读性和安全性是更推荐的做法。console.log()是一个内置函数用于在浏览器的开发者工具“控制台”(Console)中打印信息是调试和查看结果的必备工具。2.2 数据类型盒子里面装什么JavaScript 中的值有不同的类型。以下是基本数据类型// 字符串 (String) - 文本数据 let greeting Hello, World!; let name 李四; let template 你好${name}; // 模板字符串可以嵌入变量 // 数字 (Number) - 整数或浮点数 let count 10; let price 99.99; let infinity Infinity; // 布尔值 (Boolean) - 逻辑判断只有 true 或 false 两个值 let isLoggedIn true; let hasPermission false; // 空值 (Null) - 表示“空”或“无值” let emptyValue null; // 未定义 (Undefined) - 变量已声明但未赋值 let notAssigned; console.log(notAssigned); // 输出undefined // 符号 (Symbol) - 用于创建唯一的标识符进阶内容此处了解 let sym Symbol(id); // 对象 (Object) - 复杂数据的集合是引用类型 let person { name: 王五, age: 30, isStudent: false }; console.log(person.name); // 输出王五 // 数组 (Array) - 特殊对象用于存储有序的数据列表 let fruits [苹果, 香蕉, 橙子]; console.log(fruits[0]); // 输出“苹果”索引从0开始类型检查可以使用typeof操作符来查看一个值的类型。console.log(typeof greeting); // string console.log(typeof count); // number console.log(typeof isLoggedIn);// boolean console.log(typeof person); // object console.log(typeof fruits); // object (数组本质是对象) console.log(Array.isArray(fruits)); // true判断是否为数组的正确方法2.3 运算符进行计算和比较运算符用于对值进行操作。// 算术运算符 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 取余模运算 console.log(a ** b);// 1000指数 (10的3次方) // 赋值运算符 let x 5; x 3; // 等同于 x x 3 现在 x 8 x - 2; // x 6 x * 2; // x 12 x / 4; // x 3 // 比较运算符 (返回布尔值) console.log(10 5); // true console.log(10 5); // false console.log(10 10); // true console.log(5 4); // false console.log(10 10); // true (相等会进行类型转换) console.log(10 10); // true (字符串10被转换成数字10) console.log(10 10); // false (严格相等要求值和类型都相同) console.log(10 ! 10); // false (不相等) console.log(10 ! 10); // true (严格不相等) // 逻辑运算符 let condition1 true, condition2 false; console.log(condition1 condition2); // false (逻辑与两者都为真才为真) console.log(condition1 || condition2); // true (逻辑或至少一个为真即为真) console.log(!condition1); // false (逻辑非取反)注意在条件判断中推荐始终使用严格相等和!严格不相等可以避免因 JavaScript 自动类型转换隐式转换导致的难以察觉的错误。2.4 流程控制让程序做出选择程序并非总是直线执行我们需要根据条件决定执行哪段代码。// 1. if...else 语句 let score 85; if (score 90) { console.log(优秀); } else if (score 60) { console.log(及格); // 输出及格 } else { console.log(不及格); } // 2. 三元运算符 (简洁的 if...else) let status score 60 ? 通过 : 不通过; console.log(status); // 输出通过 // 3. switch 语句 (多分支选择) let day 3; let dayName; switch (day) { case 1: dayName 星期一; break; // break 防止“穿透”到下一个case case 2: dayName 星期二; break; case 3: dayName 星期三; // 匹配成功执行这里 break; default: // 所有case都不匹配时执行 dayName 未知; } console.log(dayName); // 输出星期三2.5 循环重复执行代码处理重复性任务。// 1. for 循环 (已知循环次数) for (let i 0; i 5; i) { console.log(这是第 ${i 1} 次循环); } // 输出 5 行i 从 0 到 4 // 2. while 循环 (条件为真时持续循环) let j 0; while (j 3) { console.log(j 的值是${j}); j; } // 3. do...while 循环 (至少执行一次) let k 0; do { console.log(k 的值是${k}); k; } while (k 3); // 4. 遍历数组 (常用) let colors [红色, 绿色, 蓝色]; for (let i 0; i colors.length; i) { console.log(colors[i]); } // 更简洁的 for...of 循环 for (let color of colors) { console.log(color); }3. 连接网页DOM 操作与事件处理实战掌握了基础语法我们现在要让 JavaScript 与网页互动起来。这需要通过DOM (文档对象模型)和事件来实现。3.1 什么是 DOM浏览器将 HTML 文档解析成一个树形结构这个结构就是 DOM。JavaScript 可以通过 DOM 提供的 API访问、修改、添加或删除这棵树上的任何一个节点元素、属性、文本等从而动态改变网页的内容和样式。3.2 如何获取 DOM 元素操作 DOM 的第一步是找到你要操作的那个元素。在js-quick-start文件夹中创建index.html文件!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleJS 快速入门实战/title style .highlight { background-color: yellow; } .box { padding: 20px; border: 2px solid #ccc; margin: 10px; } /style /head body h1 idmainTitle欢迎学习 JavaScript/h1 p classintro这是一个介绍段落。/p p classintro这是另一个介绍段落。/p div classbox button idmyButton点击我/button p idoutput这里会显示结果.../p /div ul iditemList li项目一/li li项目二/li /ul !-- 将 JS 代码放在 body 末尾确保 DOM 已加载 -- script srcscript.js/script /body /html在同级目录创建script.js文件我们将在这里编写 JavaScript 代码。// script.js // 1. 通过 ID 获取单个元素 (最常用、最快) const titleElement document.getElementById(mainTitle); console.log(titleElement); // 输出整个 h1 元素对象 console.log(titleElement.textContent); // 输出元素内的文本“欢迎学习 JavaScript” // 2. 通过类名获取元素集合 (返回一个类似数组的 HTMLCollection) const introParagraphs document.getElementsByClassName(intro); console.log(introParagraphs); // 包含两个 p 元素的集合 console.log(introParagraphs[0].textContent); // “这是一个介绍段落。” // 3. 通过标签名获取元素集合 const allParagraphs document.getElementsByTagName(p); console.log(allParagraphs.length); // 页面上所有 p 标签的数量 // 4. 现代、强大的选择器querySelector 和 querySelectorAll (推荐) // querySelector 返回匹配的第一个元素 const firstIntro document.querySelector(.intro); const theButton document.querySelector(#myButton); // querySelectorAll 返回匹配的所有元素 (NodeList) const allIntros document.querySelectorAll(.intro); const listItems document.querySelectorAll(#itemList li); console.log(theButton); // button idmyButton... console.log(listItems.length); // 2关键解释document对象代表整个 HTML 文档是所有 DOM 操作的起点。getElementById只获取一个元素因为 ID 应该是唯一的。getElementsByClassName和getElementsByTagName返回的是“活的”集合如果 DOM 变化集合会自动更新。querySelector使用 CSS 选择器语法非常灵活是现代开发的首选。querySelectorAll返回的 NodeList 不是“活的”集合但可以使用forEach方法遍历。3.3 如何修改 DOM 元素获取元素后我们可以修改它的内容、样式和属性。// 修改内容 titleElement.textContent JavaScript 实战开始; // 修改纯文本 titleElement.innerHTML emJavaScript/em 实战开始; // 可以解析 HTML 标签 const outputElement document.querySelector(#output); outputElement.textContent 内容已被 JS 修改。; // 修改样式 (通过 style 属性) titleElement.style.color blue; titleElement.style.fontSize 2.5rem; theButton.style.backgroundColor #4CAF50; theButton.style.color white; theButton.style.padding 10px 20px; // 修改类名 (常用于切换样式) const boxElement document.querySelector(.box); boxElement.classList.add(highlight); // 添加类 // boxElement.classList.remove(highlight); // 移除类 // boxElement.classList.toggle(highlight); // 切换类有则删无则加 // 修改属性 theButton.setAttribute(disabled, true); // 禁用按钮 // theButton.removeAttribute(disabled); // 移除禁用 console.log(theButton.getAttribute(id)); // 获取属性值myButton3.4 如何响应用户事件事件是用户或浏览器触发的动作如点击、鼠标移动、键盘按下等。我们需要“监听”这些事件并执行相应的函数事件处理程序。// 为按钮添加点击事件监听器 theButton.addEventListener(click, function() { // 当按钮被点击时这个函数会被执行 outputElement.textContent 按钮在 ${new Date().toLocaleTimeString()} 被点击了; boxElement.classList.toggle(highlight); // 每次点击切换高亮背景 }); // 也可以使用已定义的函数 function handleMouseOver() { outputElement.textContent 鼠标移到了标题上; titleElement.style.color red; } function handleMouseOut() { outputElement.textContent 鼠标移开了。; titleElement.style.color blue; // 恢复颜色 } titleElement.addEventListener(mouseover, handleMouseOver); titleElement.addEventListener(mouseout, handleMouseOut); // 键盘事件示例 (监听整个文档) document.addEventListener(keydown, function(event) { // event 对象包含了事件的详细信息 console.log(按下了键${event.key}, 键码${event.code}); if (event.key Escape) { outputElement.textContent 你按下了 ESC 键; } });3.5 动态添加和删除元素我们可以用 JavaScript 创建新的 DOM 元素并插入到页面中或者删除现有元素。const listElement document.querySelector(#itemList); // 1. 创建新元素 const newListItem document.createElement(li); newListItem.textContent 动态添加的项目三; // 2. 将新元素添加到列表末尾 listElement.appendChild(newListItem); // 3. 在特定位置插入元素 const anotherItem document.createElement(li); anotherItem.textContent 插入的项目二点五; // 在 itemList 的第一个子元素第一个 li之前插入 listElement.insertBefore(anotherItem, listElement.children[1]); // 4. 删除元素 // 假设我们要删除第一个项目 const firstItem listElement.querySelector(li); // 获取第一个 li if (firstItem) { listElement.removeChild(firstItem); } // 5. 更现代的删除方式 (ES6) const items document.querySelectorAll(#itemList li); if (items.length 0) { items[items.length - 1].remove(); // 删除最后一个 li }现在打开index.html文件到浏览器中点击按钮、移动鼠标、按键盘看看页面是如何动态变化的。这就是 JavaScript 赋予网页生命力的过程。4. 构建一个简易任务管理器综合实战我们将运用前面学到的所有知识构建一个极简的“任务管理器”。用户可以输入任务点击添加任务会显示在列表中并且可以删除单个任务。4.1 项目结构与 HTML在js-quick-start文件夹内创建一个新的todo.html文件。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title简易任务管理器/title style * { box-sizing: border-box; } body { font-family: sans-serif; max-width: 500px; margin: 40px auto; padding: 20px; } .input-area { display: flex; margin-bottom: 20px; gap: 10px;} #taskInput { flex-grow: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; } #addButton { padding: 10px 20px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; } #addButton:hover { background-color: #45a049; } #taskList { list-style: none; padding: 0; } .task-item { display: flex; justify-content: space-between; align-items: center; padding: 12px; margin-bottom: 8px; background-color: #f9f9f9; border-left: 4px solid #4CAF50; border-radius: 4px; } .task-item .delete-btn { background-color: #ff5252; color: white; border: none; padding: 5px 10px; border-radius: 3px; cursor: pointer; font-size: 0.8em; } .task-item .delete-btn:hover { background-color: #ff0000; } .empty-hint { color: #888; text-align: center; padding: 20px; } /style /head body h1 我的任务清单/h1 div classinput-area input typetext idtaskInput placeholder输入新任务... button idaddButton添加任务/button /div ul idtaskList !-- 初始提示当有任务时会被 JS 移除 -- li classempty-hint暂无任务添加一个吧/li /ul script srctodo.js/script /body /html4.2 JavaScript 逻辑实现在同级目录创建todo.js文件。// todo.js // 1. 获取 DOM 元素 const taskInput document.getElementById(taskInput); const addButton document.getElementById(addButton); const taskList document.getElementById(taskList); const emptyHint taskList.querySelector(.empty-hint); // 获取初始提示 // 2. 添加任务的函数 function addTask() { // 获取输入框的值并去除首尾空格 const taskText taskInput.value.trim(); // 输入验证如果为空则不添加 if (taskText ) { alert(请输入任务内容); taskInput.focus(); // 让光标回到输入框 return; // 退出函数 } // 如果这是第一个任务移除“暂无任务”的提示 if (emptyHint taskList.children.length 1) { // 只有提示项时 taskList.removeChild(emptyHint); } // 3. 创建新的任务列表项 const listItem document.createElement(li); listItem.className task-item; // 创建任务文本元素 const taskSpan document.createElement(span); taskSpan.textContent taskText; // 创建删除按钮 const deleteButton document.createElement(button); deleteButton.textContent 删除; deleteButton.className delete-btn; // 4. 为删除按钮添加点击事件 deleteButton.addEventListener(click, function() { // 从 taskList 中移除这个 listItem taskList.removeChild(listItem); // 如果删除后列表为空重新显示提示 if (taskList.children.length 0) { taskList.appendChild(emptyHint); } }); // 5. 将文本和按钮组装到列表项中 listItem.appendChild(taskSpan); listItem.appendChild(deleteButton); // 6. 将新列表项添加到任务列表的末尾 taskList.appendChild(listItem); // 7. 清空输入框并重新聚焦方便输入下一个任务 taskInput.value ; taskInput.focus(); } // 8. 为“添加任务”按钮绑定点击事件 addButton.addEventListener(click, addTask); // 9. 为输入框绑定回车键事件提升用户体验 taskInput.addEventListener(keydown, function(event) { if (event.key Enter) { addTask(); } }); // 10. 页面加载后让输入框自动获得焦点 window.addEventListener(DOMContentLoaded, function() { taskInput.focus(); });4.3 运行与功能验证在浏览器中打开todo.html。在输入框中输入文字例如“学习 JavaScript 基础”。点击“添加任务”按钮或按键盘上的Enter键。观察下方列表新任务应该被添加进来左侧有绿色装饰条。点击任务右侧的“删除”按钮该任务应从列表中消失。尝试添加空任务会弹出警告。删除所有任务后“暂无任务”的提示会重新出现。至此你已经完成了一个具备完整“增删”功能的前端小应用。这个项目虽然简单但涵盖了 JavaScript 入门阶段的核心概念变量、函数、DOM 操作、事件监听和条件判断。5. 常见问题与排查指南在实际编写和运行 JavaScript 时你一定会遇到各种错误。以下是新手最常见的几个问题及其解决方法。5.1 代码不执行控制台无错误现象页面正常显示但 JavaScript 功能如点击按钮无效浏览器控制台Console也没有红色报错。可能原因与排查JS 文件未正确引入或路径错误检查 HTML 中script src...的路径是否正确。打开浏览器开发者工具的“网络”(Network)标签页刷新页面查看你的.js文件是否成功加载状态码应为 200。如果状态码是 404说明路径错误。JS 代码在 DOM 元素加载前执行如果你的 JS 代码试图获取一个尚未被浏览器解析的 DOM 元素例如把script标签放在了head里那么document.getElementById会返回null。解决方案将script标签放在body的末尾或者使用DOMContentLoaded事件包装你的代码。// 推荐写法确保 DOM 完全加载后再执行脚本 document.addEventListener(DOMContentLoaded, function() { // 你的所有初始化代码放在这里 const myButton document.getElementById(myButton); // ... 其他操作 });事件监听器绑定到了错误的元素或事件类型仔细检查addEventListener的第一个参数事件名和第二个参数函数是否正确。使用console.log在函数第一行打印信息可以验证函数是否被调用。5.2 控制台报错 “Uncaught TypeError: Cannot read property ‘xxx‘ of null”现象这是最典型的错误之一控制台出现红色错误程序中断。原因你试图在一个值为null或undefined的对象上访问属性或调用方法。最常见的原因是获取 DOM 元素失败。排查找到报错的行号查看是哪个变量为null。检查获取该元素的代码如getElementById,querySelector。确认 ID 或选择器拼写是否正确大小写、横线、下划线是否与 HTML 中完全一致。确认该元素在 JS 执行时已经存在于 DOM 中参考上一点使用DOMContentLoaded。在获取元素后可以加入一个判断const el document.getElementById(someId); if (el) { // 安全地操作 el el.addEventListener(...); } else { console.error(未找到 ID 为 someId 的元素); }5.3 变量作用域问题导致 “is not defined”现象控制台报错Uncaught ReferenceError: xxx is not defined。原因你使用了一个未声明的变量或者在一个无法访问该变量的作用域内使用了它。排查与解决检查变量名拼写这是最常见的原因。理解作用域使用let和const声明的变量具有块级作用域。if (true) { let insideBlock 我在块内; } console.log(insideBlock); // 错误insideBlock 在这里不可访问在函数外部访问函数内部变量函数内部用let/const声明的变量外部无法访问。确保变量在使用前已被声明和赋值。5.4 事件处理函数中的this指向问题现象在事件处理函数中使用this时其指向不符合预期例如指向了window对象而不是触发事件的元素。原因如果使用箭头函数 () 定义事件处理函数this不会指向触发事件的 DOM 元素而是继承自外层作用域。解决方案// 方式一使用普通函数this 指向触发事件的元素 theButton.addEventListener(click, function() { console.log(this); // 指向 theButton this.style.backgroundColor red; }); // 方式二使用箭头函数但通过 event.currentTarget 获取元素 theButton.addEventListener(click, (event) { console.log(event.currentTarget); // 指向 theButton event.currentTarget.style.backgroundColor red; });下表总结了常见错误及快速排查思路问题现象最可能的原因第一步检查解决方案功能无效控制台无报错JS 文件未加载或 DOM 未就绪1. 网络面板看 JS 加载状态2. 检查script标签位置1. 修正文件路径2. 将脚本移至body末尾或使用DOMContentLoadedCannot read property ‘xxx‘ of null获取 DOM 元素失败1. 检查 ID/选择器拼写2. 在获取元素后console.log该变量1. 修正选择器2. 确保元素已存在或添加判空逻辑xxx is not defined变量未声明或作用域错误1. 检查变量名拼写2. 确认变量声明位置1. 修正拼写2. 将变量声明在合适的作用域事件函数不触发事件名写错或元素错误1. 检查addEventListener参数2. 在函数内第一行加console.log1. 修正事件名如click2. 确认绑定到了正确的元素修改样式/内容不生效CSS 优先级或属性名错误1. 检查浏览器开发者工具“元素”面板2. 查看样式是否被覆盖1. 使用element.style修改内联样式或正确切换类名2. 检查 CSS 属性名是否为驼峰如backgroundColor6. 下一步学习路径与最佳实践完成以上内容你已经跨过了 JavaScript 入门最艰难的一步。为了写出更健壮、更易维护的代码以下是一些建议和后续学习方向。6.1 从入门到进阶学习路线图巩固基础反复练习本章的实战项目尝试为其添加新功能如“标记完成”、“任务过滤”、“数据持久化存到浏览器本地存储”等。深入核心概念函数理解函数声明、表达式、箭头函数、参数、返回值、高阶函数。对象与面向对象理解构造函数、原型链、ES6 的class语法。数组与迭代方法熟练掌握map,filter,reduce,find,forEach等这是处理数据的利器。异步编程这是 JavaScript 的难点和重点。理解回调函数、Promise、async/await学习如何使用fetchAPI 从网络获取数据。学习 ES6 新特性如模板字符串、解构赋值、展开运算符、模块化import/export等它们能极大提升开发效率和代码可读性。探索现代开发流程学习使用npm包管理器、代码格式化工具Prettier、代码检查工具ESLint以及模块打包工具如 Webpack, Vite。选择一个框架在扎实的原生 JS 基础上学习 React, Vue 或 Angular 等主流前端框架它们能帮助你更高效地构建复杂应用。6.2 编码最佳实践从现在开始养成习惯使用const和let避免varconst用于声明不会重新赋值的变量let用于声明会改变的变量。这能使代码意图更清晰并减少意外错误。使用严格相等 (/!)避免隐式类型转换带来的诡异 bug。为函数和变量起有意义的名字userList比list好calculateTotalPrice比calc好。保持函数功能单一一个函数只做一件事。如果函数太长或做了太多事考虑拆分它。多用console.log进行调试这是最直接有效的调试方式。但项目上线前记得清理或使用更高级的日志工具。代码格式化保持一致的缩进通常为 2 或 4 个空格、空格和换行风格。可以使用编辑器的格式化功能。注释要解释“为什么”而不是“是什么”代码本身应该能说明“是什么”注释应该解释复杂的逻辑或特殊决策的原因。6.3 开发环境与调试技巧精通浏览器开发者工具这是前端开发者的“瑞士军刀”。重点学习Console控制台运行 JS 代码、查看日志和错误。Elements元素查看和实时编辑 DOM 与 CSS。Sources源代码设置断点进行单步调试这是排查复杂逻辑问题的终极武器。Network网络查看所有网络请求分析性能问题。使用代码编辑器VS Code 配合 ESLint、Prettier、Live Server 等插件能极大提升开发体验和代码质量。学习编程是一个不断实践和解决问题的过程。不要害怕犯错控制台里的每一个红色错误都是你进步的阶梯。从今天这个小项目出发不断尝试修改、扩展、重构你会在解决实际问题的过程中快速掌握 JavaScript 的精髓。