diff --git a/03-javascript-core/01-variables-and-console/README.md b/03-javascript-core/01-variables-and-console/README.md new file mode 100644 index 0000000..0fe7cd5 --- /dev/null +++ b/03-javascript-core/01-variables-and-console/README.md @@ -0,0 +1,27 @@ +# 练习 1:变量和控制台输出 + +## 目标 + +学会声明变量、修改变量,并把结果打印出来。 + +## 你要练什么 + +- `const` +- `let` +- 字符串拼接 +- `console.log()` + +## 任务 + +请完成一个“学习档案”输出脚本,要求: + +- 声明用户名 +- 声明当前学习阶段 +- 声明已完成练习数 +- 修改一次学习阶段或练习数 +- 最后输出 3 行清晰的结果 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/01-variables-and-console/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/01-variables-and-console/answer.js) diff --git a/03-javascript-core/01-variables-and-console/answer.js b/03-javascript-core/01-variables-and-console/answer.js new file mode 100644 index 0000000..c9e8550 --- /dev/null +++ b/03-javascript-core/01-variables-and-console/answer.js @@ -0,0 +1,9 @@ +const userName = "小周"; +let currentStage = "JavaScript 入门"; +let completedExercises = 2; + +completedExercises = completedExercises + 1; + +console.log("学习者:" + userName); +console.log("当前阶段:" + currentStage); +console.log("已完成练习数:" + completedExercises); diff --git a/03-javascript-core/01-variables-and-console/starter.js b/03-javascript-core/01-variables-and-console/starter.js new file mode 100644 index 0000000..c05ba37 --- /dev/null +++ b/03-javascript-core/01-variables-and-console/starter.js @@ -0,0 +1,9 @@ +const userName = ""; +let currentStage = ""; +let completedExercises = 0; + +// 任务: +// 1. 给上面的变量赋一个合理值 +// 2. 修改一次 currentStage 或 completedExercises +// 3. 输出 3 行学习信息 +// 例如:学习者:小周 diff --git a/03-javascript-core/02-data-types-and-conversion/README.md b/03-javascript-core/02-data-types-and-conversion/README.md new file mode 100644 index 0000000..2c16dfc --- /dev/null +++ b/03-javascript-core/02-data-types-and-conversion/README.md @@ -0,0 +1,29 @@ +# 练习 2:数据类型和类型转换 + +## 目标 + +认识常见数据类型,并学会把字符串数字转成真正的数字。 + +## 你要练什么 + +- `string` +- `number` +- `boolean` +- `typeof` +- `Number()` +- 模板字符串 + +## 任务 + +请完成一个“课程报名信息”脚本,要求: + +- 声明姓名、年龄、是否已付费 +- 年龄先用字符串保存 +- 再把年龄转换为数字 +- 输出每个变量的值和类型 +- 最后输出一句完整报名信息 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/02-data-types-and-conversion/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/02-data-types-and-conversion/answer.js) diff --git a/03-javascript-core/02-data-types-and-conversion/answer.js b/03-javascript-core/02-data-types-and-conversion/answer.js new file mode 100644 index 0000000..ac36b2a --- /dev/null +++ b/03-javascript-core/02-data-types-and-conversion/answer.js @@ -0,0 +1,12 @@ +const studentName = "林晨"; +const ageText = "21"; +const hasPaid = true; + +const ageNumber = Number(ageText); + +console.log(studentName, typeof studentName); +console.log(ageText, typeof ageText); +console.log(ageNumber, typeof ageNumber); +console.log(hasPaid, typeof hasPaid); + +console.log(`${studentName} 今年 ${ageNumber} 岁,付费状态:${hasPaid}`); diff --git a/03-javascript-core/02-data-types-and-conversion/starter.js b/03-javascript-core/02-data-types-and-conversion/starter.js new file mode 100644 index 0000000..d5af69d --- /dev/null +++ b/03-javascript-core/02-data-types-and-conversion/starter.js @@ -0,0 +1,8 @@ +const studentName = "林晨"; +const ageText = "21"; +const hasPaid = true; + +// 任务: +// 1. 把 ageText 转成数字,保存到 ageNumber +// 2. 分别输出 studentName、ageText、ageNumber、hasPaid 的类型 +// 3. 用模板字符串输出一句报名信息 diff --git a/03-javascript-core/03-operators-and-conditions/README.md b/03-javascript-core/03-operators-and-conditions/README.md new file mode 100644 index 0000000..ca168a4 --- /dev/null +++ b/03-javascript-core/03-operators-and-conditions/README.md @@ -0,0 +1,28 @@ +# 练习 3:运算符和条件判断 + +## 目标 + +学会比较数据,并根据不同条件输出不同结果。 + +## 你要练什么 + +- 算术运算符 +- 比较运算符 +- 逻辑运算符 +- `if...else if...else` + +## 任务 + +请完成一个“成绩评级”脚本,要求: + +- 根据分数计算是否及格 +- 根据分数输出等级 +- 90 分及以上为 A +- 80 到 89 为 B +- 60 到 79 为 C +- 60 以下为 D + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/03-operators-and-conditions/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/03-operators-and-conditions/answer.js) diff --git a/03-javascript-core/03-operators-and-conditions/answer.js b/03-javascript-core/03-operators-and-conditions/answer.js new file mode 100644 index 0000000..7d78f87 --- /dev/null +++ b/03-javascript-core/03-operators-and-conditions/answer.js @@ -0,0 +1,18 @@ +const score = 86; + +let passed = score >= 60; +let grade = ""; + +if (score >= 90) { + grade = "A"; +} else if (score >= 80) { + grade = "B"; +} else if (score >= 60) { + grade = "C"; +} else { + grade = "D"; +} + +console.log("分数:", score); +console.log("是否及格:", passed); +console.log("等级:", grade); diff --git a/03-javascript-core/03-operators-and-conditions/starter.js b/03-javascript-core/03-operators-and-conditions/starter.js new file mode 100644 index 0000000..a4ff06d --- /dev/null +++ b/03-javascript-core/03-operators-and-conditions/starter.js @@ -0,0 +1,9 @@ +const score = 86; + +// 任务: +// 1. 用布尔值保存是否及格 +// 2. 用 if...else if...else 判断等级 +// 3. 输出分数、是否及格、等级 + +let passed = false; +let grade = ""; diff --git a/03-javascript-core/04-loops/README.md b/03-javascript-core/04-loops/README.md new file mode 100644 index 0000000..d7f3046 --- /dev/null +++ b/03-javascript-core/04-loops/README.md @@ -0,0 +1,26 @@ +# 练习 4:循环 + +## 目标 + +学会用循环处理重复任务,而不是手写很多遍。 + +## 你要练什么 + +- `for` +- `while` +- 累加 +- 条件跳过 + +## 任务 + +请完成一个“学习打卡统计”脚本,要求: + +- 用 `for` 输出第 1 天到第 7 天的打卡信息 +- 跳过第 4 天 +- 再用 `while` 计算 1 到 5 的总和 +- 输出最终总和 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/04-loops/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/04-loops/answer.js) diff --git a/03-javascript-core/04-loops/answer.js b/03-javascript-core/04-loops/answer.js new file mode 100644 index 0000000..d649282 --- /dev/null +++ b/03-javascript-core/04-loops/answer.js @@ -0,0 +1,17 @@ +for (let day = 1; day <= 7; day += 1) { + if (day === 4) { + continue; + } + + console.log(`第 ${day} 天:完成学习打卡`); +} + +let current = 1; +let sum = 0; + +while (current <= 5) { + sum += current; + current += 1; +} + +console.log("1 到 5 的总和:", sum); diff --git a/03-javascript-core/04-loops/starter.js b/03-javascript-core/04-loops/starter.js new file mode 100644 index 0000000..ed6bf23 --- /dev/null +++ b/03-javascript-core/04-loops/starter.js @@ -0,0 +1,7 @@ +// 任务: +// 1. 用 for 输出第 1 天到第 7 天 +// 2. 第 4 天跳过,不输出 +// 3. 用 while 计算 1 到 5 的总和 +// 4. 输出 sum + +let sum = 0; diff --git a/03-javascript-core/05-functions/README.md b/03-javascript-core/05-functions/README.md new file mode 100644 index 0000000..ed0fcf1 --- /dev/null +++ b/03-javascript-core/05-functions/README.md @@ -0,0 +1,27 @@ +# 练习 5:函数 + +## 目标 + +学会把一段逻辑封装成函数,并通过参数和返回值复用它。 + +## 你要练什么 + +- 函数声明 +- 参数 +- `return` +- 函数调用 + +## 任务 + +请完成一个“学习成绩处理器”,要求: + +- 写一个 `getAverage` 函数 +- 接收 3 个分数参数 +- 返回平均分 +- 再写一个 `getLevel` 函数 +- 根据平均分返回“优秀”“良好”“继续努力” + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/05-functions/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/05-functions/answer.js) diff --git a/03-javascript-core/05-functions/answer.js b/03-javascript-core/05-functions/answer.js new file mode 100644 index 0000000..59ad4fa --- /dev/null +++ b/03-javascript-core/05-functions/answer.js @@ -0,0 +1,21 @@ +function getAverage(score1, score2, score3) { + return (score1 + score2 + score3) / 3; +} + +function getLevel(average) { + if (average >= 85) { + return "优秀"; + } + + if (average >= 70) { + return "良好"; + } + + return "继续努力"; +} + +const average = getAverage(88, 92, 79); +const level = getLevel(average); + +console.log("平均分:", average); +console.log("等级:", level); diff --git a/03-javascript-core/05-functions/starter.js b/03-javascript-core/05-functions/starter.js new file mode 100644 index 0000000..d4d4448 --- /dev/null +++ b/03-javascript-core/05-functions/starter.js @@ -0,0 +1,11 @@ +function getAverage(score1, score2, score3) { + // 返回平均分 +} + +function getLevel(average) { + // 根据平均分返回等级描述 +} + +// 任务: +// 1. 调用上面两个函数 +// 2. 输出平均分和等级 diff --git a/03-javascript-core/06-arrays/README.md b/03-javascript-core/06-arrays/README.md new file mode 100644 index 0000000..0bbb1ea --- /dev/null +++ b/03-javascript-core/06-arrays/README.md @@ -0,0 +1,27 @@ +# 练习 6:数组 + +## 目标 + +学会保存一组同类数据,并对数组做基础读写。 + +## 你要练什么 + +- 数组声明 +- 下标访问 +- `length` +- `push()` +- 遍历数组 + +## 任务 + +请完成一个“学习清单”脚本,要求: + +- 创建一个包含 3 个学习主题的数组 +- 新增 1 个学习主题 +- 输出数组长度 +- 依次输出每个学习主题 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/06-arrays/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/06-arrays/answer.js) diff --git a/03-javascript-core/06-arrays/answer.js b/03-javascript-core/06-arrays/answer.js new file mode 100644 index 0000000..86ad356 --- /dev/null +++ b/03-javascript-core/06-arrays/answer.js @@ -0,0 +1,9 @@ +const topics = ["HTML", "CSS", "JavaScript"]; + +topics.push("DOM"); + +console.log("学习主题数量:", topics.length); + +for (let index = 0; index < topics.length; index += 1) { + console.log(`第 ${index + 1} 项:${topics[index]}`); +} diff --git a/03-javascript-core/06-arrays/starter.js b/03-javascript-core/06-arrays/starter.js new file mode 100644 index 0000000..c068cc3 --- /dev/null +++ b/03-javascript-core/06-arrays/starter.js @@ -0,0 +1,6 @@ +const topics = ["HTML", "CSS", "JavaScript"]; + +// 任务: +// 1. 往 topics 里新增一个主题 +// 2. 输出 topics 的长度 +// 3. 用循环输出每一项 diff --git a/03-javascript-core/07-objects/README.md b/03-javascript-core/07-objects/README.md new file mode 100644 index 0000000..9d17541 --- /dev/null +++ b/03-javascript-core/07-objects/README.md @@ -0,0 +1,27 @@ +# 练习 7:对象 + +## 目标 + +学会用对象描述一个事物的多个属性。 + +## 你要练什么 + +- 对象字面量 +- 属性读取 +- 属性修改 +- 新增属性 + +## 任务 + +请完成一个“课程对象”脚本,要求: + +- 创建一个课程对象 +- 至少包含名称、课时、是否完结 +- 修改其中一个属性 +- 新增一个老师属性 +- 输出完整对象和其中两个单独属性 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/07-objects/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/07-objects/answer.js) diff --git a/03-javascript-core/07-objects/answer.js b/03-javascript-core/07-objects/answer.js new file mode 100644 index 0000000..f2c321c --- /dev/null +++ b/03-javascript-core/07-objects/answer.js @@ -0,0 +1,12 @@ +const course = { + title: "JavaScript 核心", + lessons: 12, + finished: false, +}; + +course.finished = true; +course.teacher = "周老师"; + +console.log(course); +console.log("课程名称:", course.title); +console.log("授课老师:", course.teacher); diff --git a/03-javascript-core/07-objects/starter.js b/03-javascript-core/07-objects/starter.js new file mode 100644 index 0000000..3a63477 --- /dev/null +++ b/03-javascript-core/07-objects/starter.js @@ -0,0 +1,11 @@ +const course = { + title: "JavaScript 核心", + lessons: 12, + finished: false, +}; + +// 任务: +// 1. 修改 finished +// 2. 新增 teacher 属性 +// 3. 输出完整对象 +// 4. 输出 title 和 teacher diff --git a/03-javascript-core/08-built-in-methods/README.md b/03-javascript-core/08-built-in-methods/README.md new file mode 100644 index 0000000..f4d31d4 --- /dev/null +++ b/03-javascript-core/08-built-in-methods/README.md @@ -0,0 +1,26 @@ +# 练习 8:常见内置方法 + +## 目标 + +学会使用几个常见的字符串和数组方法,减少重复代码。 + +## 你要练什么 + +- `trim()` +- `toUpperCase()` +- `includes()` +- `join()` + +## 任务 + +请完成一个“标签清洗器”脚本,要求: + +- 把一段带空格的文本去掉首尾空格 +- 把结果转成大写 +- 判断里面是否包含 `JS` +- 把一个标签数组拼成一个字符串输出 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/08-built-in-methods/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/08-built-in-methods/answer.js) diff --git a/03-javascript-core/08-built-in-methods/answer.js b/03-javascript-core/08-built-in-methods/answer.js new file mode 100644 index 0000000..cf6cc46 --- /dev/null +++ b/03-javascript-core/08-built-in-methods/answer.js @@ -0,0 +1,12 @@ +const rawTitle = " js 核心练习 "; +const tags = ["变量", "条件", "函数"]; + +const cleanTitle = rawTitle.trim(); +const upperTitle = cleanTitle.toUpperCase(); +const hasJS = upperTitle.includes("JS"); +const tagLine = tags.join("、"); + +console.log("清洗后标题:", cleanTitle); +console.log("大写标题:", upperTitle); +console.log("是否包含 JS:", hasJS); +console.log("标签列表:", tagLine); diff --git a/03-javascript-core/08-built-in-methods/starter.js b/03-javascript-core/08-built-in-methods/starter.js new file mode 100644 index 0000000..7c63f05 --- /dev/null +++ b/03-javascript-core/08-built-in-methods/starter.js @@ -0,0 +1,8 @@ +const rawTitle = " js 核心练习 "; +const tags = ["变量", "条件", "函数"]; + +// 任务: +// 1. 去掉 rawTitle 两端空格 +// 2. 转成大写 +// 3. 判断是否包含 JS +// 4. 把 tags 用顿号连接成一句话 diff --git a/03-javascript-core/09-scope-and-closure/README.md b/03-javascript-core/09-scope-and-closure/README.md new file mode 100644 index 0000000..fe1f48b --- /dev/null +++ b/03-javascript-core/09-scope-and-closure/README.md @@ -0,0 +1,28 @@ +# 练习 9:闭包入门 + +## 目标 + +初步理解闭包为什么能把外层变量“记住”。 + +## 你要练什么 + +- 外层变量 +- 内层函数 +- 闭包的基本效果 +- 多个闭包实例互不影响 + +## 任务 + +请完成一个“计数器工厂”脚本,要求: + +- 写一个 `createCounter` 函数 +- 在函数内部定义 `count` +- 返回一个内部函数 +- 每次调用内部函数时,`count` 都加 1 +- 创建两个不同的计数器 +- 观察为什么它们各自记住了自己的 `count` + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/09-scope-and-closure/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/09-scope-and-closure/answer.js) diff --git a/03-javascript-core/09-scope-and-closure/answer.js b/03-javascript-core/09-scope-and-closure/answer.js new file mode 100644 index 0000000..5336727 --- /dev/null +++ b/03-javascript-core/09-scope-and-closure/answer.js @@ -0,0 +1,16 @@ +function createCounter() { + let count = 0; + + return function () { + count += 1; + return count; + }; +} + +const counterA = createCounter(); +const counterB = createCounter(); + +console.log("counterA 第一次:", counterA()); +console.log("counterA 第二次:", counterA()); +console.log("counterB 第一次:", counterB()); +console.log("每次调用 createCounter 都会创建一个新的闭包环境。"); diff --git a/03-javascript-core/09-scope-and-closure/starter.js b/03-javascript-core/09-scope-and-closure/starter.js new file mode 100644 index 0000000..4ff638c --- /dev/null +++ b/03-javascript-core/09-scope-and-closure/starter.js @@ -0,0 +1,11 @@ +function createCounter() { + let count = 0; + + // 返回一个函数 +} + +// 任务: +// 1. 创建 counterA 和 counterB +// 2. 连续调用 counterA 两次 +// 3. 再调用 counterB 一次 +// 4. 观察为什么两个计数器互不影响 diff --git a/03-javascript-core/10-final-mini-app/README.md b/03-javascript-core/10-final-mini-app/README.md new file mode 100644 index 0000000..7537039 --- /dev/null +++ b/03-javascript-core/10-final-mini-app/README.md @@ -0,0 +1,33 @@ +# 练习 10:基础阶段综合小程序 + +## 目标 + +把前面基础阶段学过的变量、条件、函数、数组、对象组合起来,完成一个完整的小练习。 + +## 项目名称 + +基础学习进度统计器 + +## 任务 + +请完成一个控制台版学习进度统计器,要求至少包含: + +- 一个 `student` 对象 +- 一个 `scores` 数组 +- 一个计算平均分的函数 +- 一个判断等级的函数 +- 输出姓名、平均分、等级 +- 如果平均分大于等于 80,再输出“可以进入下一阶段” + +## 自检标准 + +- 是否把数据和逻辑拆开了 +- 是否写了可复用函数 +- 是否正确读取数组和对象数据 +- 条件分支是否完整 +- 输出结果是否清晰 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/10-final-mini-app/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/10-final-mini-app/answer.js) diff --git a/03-javascript-core/10-final-mini-app/answer.js b/03-javascript-core/10-final-mini-app/answer.js new file mode 100644 index 0000000..98a167f --- /dev/null +++ b/03-javascript-core/10-final-mini-app/answer.js @@ -0,0 +1,40 @@ +const student = { + name: "林晨", + stage: "JavaScript 核心", +}; + +const scores = [78, 85, 92]; + +function getAverageScore(list) { + let total = 0; + + for (let index = 0; index < list.length; index += 1) { + total += list[index]; + } + + return total / list.length; +} + +function getLevel(average) { + if (average >= 85) { + return "优秀"; + } + + if (average >= 70) { + return "良好"; + } + + return "继续努力"; +} + +const average = getAverageScore(scores); +const level = getLevel(average); + +console.log("姓名:", student.name); +console.log("阶段:", student.stage); +console.log("平均分:", average); +console.log("等级:", level); + +if (average >= 80) { + console.log("可以进入下一阶段"); +} diff --git a/03-javascript-core/10-final-mini-app/starter.js b/03-javascript-core/10-final-mini-app/starter.js new file mode 100644 index 0000000..2752489 --- /dev/null +++ b/03-javascript-core/10-final-mini-app/starter.js @@ -0,0 +1,20 @@ +const student = { + name: "林晨", + stage: "JavaScript 核心", +}; + +const scores = [78, 85, 92]; + +function getAverageScore(list) { + // 计算平均分 +} + +function getLevel(average) { + // 返回等级 +} + +// 任务: +// 1. 计算平均分 +// 2. 计算等级 +// 3. 输出姓名、阶段、平均分、等级 +// 4. 如果平均分 >= 80,输出“可以进入下一阶段” diff --git a/03-javascript-core/11-var-and-scope/README.md b/03-javascript-core/11-var-and-scope/README.md new file mode 100644 index 0000000..1cba273 --- /dev/null +++ b/03-javascript-core/11-var-and-scope/README.md @@ -0,0 +1,30 @@ +# 练习 11:var、let、const 与提升 + +## 目标 + +理解 `var`、`let`、`const` 的基本区别,尤其是作用域和提升差异。 + +## 你要练什么 + +- `var` +- `let` +- `const` +- 变量提升 +- 块级作用域 +- 函数作用域 + +## 任务 + +请完成一个“作用域观察”脚本,要求: + +- 观察 `var` 声明前为什么能访问到 `undefined` +- 用 `var` 声明一个函数内部变量 +- 用 `let` 声明一个代码块内部变量 +- 在可访问的位置输出它们 +- 观察为什么 `var` 在块外还能访问,而 `let` 不行 +- 再写一段代码证明 `const` 不能被重新赋值 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/11-var-and-scope/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/11-var-and-scope/answer.js) diff --git a/03-javascript-core/11-var-and-scope/answer.js b/03-javascript-core/11-var-and-scope/answer.js new file mode 100644 index 0000000..72ff569 --- /dev/null +++ b/03-javascript-core/11-var-and-scope/answer.js @@ -0,0 +1,28 @@ +console.log("var 声明前:", lessonType); +var lessonType = "JavaScript"; + +console.log("var 声明后:", lessonType); +// console.log("let 声明前:", chapterType); +// let 在声明前处于暂时性死区,直接访问会报错。 + +function compareScope() { + if (true) { + var lessonName = "变量"; + let chapterName = "作用域"; + const stage = "进阶"; + + console.log("块内:", lessonName, chapterName, stage); + } + + console.log("块外仍能访问 var:", lessonName); + // console.log(chapterName); + // chapterName 是 let 声明的块级作用域变量,离开 if 代码块后就不能访问。 +} + +compareScope(); + +const level = "核心阶段"; +console.log("const 初始值:", level); + +// level = "下一阶段"; +// const 不能被重新赋值,否则会报错。 diff --git a/03-javascript-core/11-var-and-scope/starter.js b/03-javascript-core/11-var-and-scope/starter.js new file mode 100644 index 0000000..57332ef --- /dev/null +++ b/03-javascript-core/11-var-and-scope/starter.js @@ -0,0 +1,27 @@ +console.log("var 声明前:", lessonType); +var lessonType = "JavaScript"; + +// 如果你取消下面两行注释,会报错,因为 let 在声明前不能访问。 +// console.log("let 声明前:", chapterType); +// let chapterType = "作用域"; + +function compareScope() { + if (true) { + var lessonName = "变量"; + let chapterName = "作用域"; + const stage = "进阶"; + + console.log("块内:", lessonName, chapterName, stage); + } + + // 任务: + // 1. 输出 lessonName + // 2. 不要直接在这里输出 chapterName,否则会报错 + // 3. 用一句注释说明为什么 +} + +compareScope(); + +// 任务: +// 4. 试着重新给 const 声明的值赋值 +// 5. 观察会发生什么 diff --git a/03-javascript-core/12-this-keyword/README.md b/03-javascript-core/12-this-keyword/README.md new file mode 100644 index 0000000..542d6d7 --- /dev/null +++ b/03-javascript-core/12-this-keyword/README.md @@ -0,0 +1,27 @@ +# 练习 12:this + +## 目标 + +理解 `this` 会随着调用方式不同而变化。 + +## 你要练什么 + +- 对象方法调用 +- 普通函数调用 +- 箭头函数继承外层 `this` +- `this` 指向 + +## 任务 + +请完成一个“学习者对象”脚本,要求: + +- 创建一个带 `name` 和 `stage` 的对象 +- 写一个对象方法,方法内部用 `this.name` +- 取出这个方法单独调用,观察 `this` 变化 +- 再写一个返回箭头函数的方法,观察箭头函数为什么还能拿到对象的 `this` +- 输出 3 种调用结果 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/12-this-keyword/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/12-this-keyword/answer.js) diff --git a/03-javascript-core/12-this-keyword/answer.js b/03-javascript-core/12-this-keyword/answer.js new file mode 100644 index 0000000..f41b8ca --- /dev/null +++ b/03-javascript-core/12-this-keyword/answer.js @@ -0,0 +1,26 @@ +const student = { + name: "林晨", + stage: "JavaScript 核心", + sayHello() { + const currentName = this && this.name ? this.name : "未知调用者"; + const currentStage = this && this.stage ? this.stage : "未知阶段"; + console.log(`你好,我是 ${currentName},正在学习 ${currentStage}`); + }, + createArrowReporter() { + return () => { + console.log(`箭头函数继承到的 this.name:${this.name}`); + }; + }, +}; + +student.sayHello(); + +const detachedHello = student.sayHello; +detachedHello(); + +const arrowReporter = student.createArrowReporter(); +arrowReporter(); + +console.log("对象方法里的 this 通常指向调用它的对象。"); +console.log("脱离对象单独调用后,普通函数里的 this 会跟着调用方式变化。"); +console.log("箭头函数没有自己的 this,它会继承创建它时外层的 this。"); diff --git a/03-javascript-core/12-this-keyword/starter.js b/03-javascript-core/12-this-keyword/starter.js new file mode 100644 index 0000000..4faec8d --- /dev/null +++ b/03-javascript-core/12-this-keyword/starter.js @@ -0,0 +1,18 @@ +const student = { + name: "林晨", + stage: "JavaScript 核心", + sayHello() { + // 任务: + // 1. 用 this.name 输出问候语 + }, + createArrowReporter() { + // 任务: + // 2. 返回一个箭头函数 + // 3. 在箭头函数里输出 this.name + }, +}; + +// 任务: +// 4. 调用 student.sayHello() +// 5. 把 student.sayHello 赋值给 detachedHello 再调用 +// 6. 调用 createArrowReporter 返回的新函数 diff --git a/03-javascript-core/13-array-high-order-methods/README.md b/03-javascript-core/13-array-high-order-methods/README.md new file mode 100644 index 0000000..7522b99 --- /dev/null +++ b/03-javascript-core/13-array-high-order-methods/README.md @@ -0,0 +1,30 @@ +# 练习 13:数组高阶函数 + +## 目标 + +学会使用数组高阶函数处理一组数据。 + +## 你要练什么 + +- `map()` +- `filter()` +- `reduce()` +- `find()` +- `some()` +- `every()` + +## 任务 + +请完成一个“学习成绩分析”脚本,要求: + +- 用 `map` 生成带单位的新数组 +- 用 `filter` 找出及格成绩 +- 用 `reduce` 计算总分 +- 用 `find` 找出第一条大于等于 90 的成绩 +- 用 `some` 判断是否有人不及格 +- 用 `every` 判断是否全部完成考试 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/13-array-high-order-methods/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/13-array-high-order-methods/answer.js) diff --git a/03-javascript-core/13-array-high-order-methods/answer.js b/03-javascript-core/13-array-high-order-methods/answer.js new file mode 100644 index 0000000..f53acd1 --- /dev/null +++ b/03-javascript-core/13-array-high-order-methods/answer.js @@ -0,0 +1,37 @@ +const scores = [58, 76, 91, 84]; +const students = [ + { name: "小周", finished: true }, + { name: "小林", finished: true }, + { name: "小陈", finished: false }, +]; + +const scoreLabels = scores.map(function (score) { + return `${score}分`; +}); + +const passedScores = scores.filter(function (score) { + return score >= 60; +}); + +const totalScore = scores.reduce(function (total, score) { + return total + score; +}, 0); + +const topScore = scores.find(function (score) { + return score >= 90; +}); + +const hasFailedScore = scores.some(function (score) { + return score < 60; +}); + +const allFinished = students.every(function (student) { + return student.finished === true; +}); + +console.log("带单位成绩:", scoreLabels); +console.log("及格成绩:", passedScores); +console.log("总分:", totalScore); +console.log("第一个 90 分以上:", topScore); +console.log("是否存在不及格:", hasFailedScore); +console.log("是否全部完成:", allFinished); diff --git a/03-javascript-core/13-array-high-order-methods/starter.js b/03-javascript-core/13-array-high-order-methods/starter.js new file mode 100644 index 0000000..7a5b5b5 --- /dev/null +++ b/03-javascript-core/13-array-high-order-methods/starter.js @@ -0,0 +1,14 @@ +const scores = [58, 76, 91, 84]; +const students = [ + { name: "小周", finished: true }, + { name: "小林", finished: true }, + { name: "小陈", finished: false }, +]; + +// 任务: +// 1. 用 map 生成 ["58分", ...] +// 2. 用 filter 筛出及格分 +// 3. 用 reduce 计算总分 +// 4. 用 find 找到第一个 >= 90 的分数 +// 5. 用 some 判断是否存在不及格 +// 6. 用 every 判断 students 是否都 finished 为 true diff --git a/03-javascript-core/14-memory-and-execution/README.md b/03-javascript-core/14-memory-and-execution/README.md new file mode 100644 index 0000000..a7bf36b --- /dev/null +++ b/03-javascript-core/14-memory-and-execution/README.md @@ -0,0 +1,26 @@ +# 练习 14:内存和执行 + +## 目标 + +理解“值”和“引用”的区别,以及函数执行时数据为什么会变化。 + +## 你要练什么 + +- 基本类型复制 +- 引用类型共享 +- 函数执行顺序 +- 参数传递 + +## 任务 + +请完成一个“数据变化观察”脚本,要求: + +- 比较基本类型复制后是否互相影响 +- 比较对象复制后是否互相影响 +- 写两个函数观察执行顺序 +- 写一个函数修改传入对象,观察外部对象为什么会变化 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/14-memory-and-execution/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/14-memory-and-execution/answer.js) diff --git a/03-javascript-core/14-memory-and-execution/answer.js b/03-javascript-core/14-memory-and-execution/answer.js new file mode 100644 index 0000000..d572d46 --- /dev/null +++ b/03-javascript-core/14-memory-and-execution/answer.js @@ -0,0 +1,39 @@ +let scoreA = 80; +let scoreB = scoreA; + +scoreB = 95; + +console.log("基本类型 scoreA:", scoreA); +console.log("基本类型 scoreB:", scoreB); +console.log("基本类型复制后,两个变量互不影响。"); + +const userA = { + name: "小周", + city: "上海", +}; + +const userB = userA; +userB.city = "深圳"; + +console.log("对象 userA:", userA); +console.log("对象 userB:", userB); +console.log("对象变量保存的是引用,所以改 userB 会影响 userA。"); + +function printStepOne() { + console.log("步骤一:先进入第一个函数"); +} + +function printStepTwo() { + console.log("步骤二:再执行第二个函数"); +} + +function updateUser(user) { + user.city = "杭州"; + console.log("函数内部修改后的 user:", user); +} + +printStepOne(); +printStepTwo(); +updateUser(userA); + +console.log("函数执行结束后的 userA:", userA); diff --git a/03-javascript-core/14-memory-and-execution/starter.js b/03-javascript-core/14-memory-and-execution/starter.js new file mode 100644 index 0000000..61f9307 --- /dev/null +++ b/03-javascript-core/14-memory-and-execution/starter.js @@ -0,0 +1,28 @@ +let scoreA = 80; +let scoreB = scoreA; + +const userA = { + name: "小周", + city: "上海", +}; + +const userB = userA; + +function printStepOne() { + console.log("步骤一"); +} + +function printStepTwo() { + console.log("步骤二"); +} + +function updateUser(user) { + // 任务: + // 1. 修改 user.city +} + +// 任务: +// 2. 修改 scoreB,观察 scoreA 是否变化 +// 3. 修改 userB.city,观察 userA.city 是否变化 +// 4. 按顺序调用 printStepOne 和 printStepTwo +// 5. 调用 updateUser(userA) diff --git a/03-javascript-core/15-switch-break-and-empty-values/README.md b/03-javascript-core/15-switch-break-and-empty-values/README.md new file mode 100644 index 0000000..1a52d0c --- /dev/null +++ b/03-javascript-core/15-switch-break-and-empty-values/README.md @@ -0,0 +1,28 @@ +# 练习 15:switch、break 和空值判断 + +## 目标 + +学会在分支判断里使用 `switch`,并区分 `undefined`、`null` 这两种常见空值。 + +## 你要练什么 + +- `switch` +- `break` +- `undefined` +- `null` +- 空值判断 + +## 任务 + +请完成一个“学习记录检查器”脚本,要求: + +- 用 `switch` 根据学习状态输出不同说明 +- 观察 `undefined` 和 `null` 的区别 +- 用循环读取学习记录 +- 如果读到 `undefined` 或 `null`,立即用 `break` 停止循环 +- 输出停止前已经读取到的内容 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/15-switch-break-and-empty-values/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/15-switch-break-and-empty-values/answer.js) diff --git a/03-javascript-core/15-switch-break-and-empty-values/answer.js b/03-javascript-core/15-switch-break-and-empty-values/answer.js new file mode 100644 index 0000000..7759822 --- /dev/null +++ b/03-javascript-core/15-switch-break-and-empty-values/answer.js @@ -0,0 +1,41 @@ +const learningStatus = "review"; +const records = ["变量", "条件", "函数", null, "对象"]; + +let optionalNote; +const finalComment = null; +let statusText = ""; +const finishedRecords = []; + +switch (learningStatus) { + case "basic": + statusText = "正在完成基础阶段"; + break; + case "review": + statusText = "正在进入总复习"; + break; + case "done": + statusText = "当前阶段已经完成"; + break; + default: + statusText = "状态未知"; + break; +} + +console.log("状态说明:", statusText); +console.log("optionalNote:", optionalNote); +console.log("optionalNote 是否为 undefined:", optionalNote === undefined); +console.log("finalComment:", finalComment); +console.log("finalComment 是否为 null:", finalComment === null); + +for (let index = 0; index < records.length; index += 1) { + const currentRecord = records[index]; + + if (currentRecord === undefined || currentRecord === null) { + console.log(`第 ${index + 1} 项为空值,停止读取。`); + break; + } + + finishedRecords.push(currentRecord); +} + +console.log("停止前已读取内容:", finishedRecords); diff --git a/03-javascript-core/15-switch-break-and-empty-values/starter.js b/03-javascript-core/15-switch-break-and-empty-values/starter.js new file mode 100644 index 0000000..700f143 --- /dev/null +++ b/03-javascript-core/15-switch-break-and-empty-values/starter.js @@ -0,0 +1,14 @@ +const learningStatus = "review"; +const records = ["变量", "条件", "函数", null, "对象"]; + +let optionalNote; +const finalComment = null; +let statusText = ""; +const finishedRecords = []; + +// 任务: +// 1. 用 switch 给 learningStatus 生成说明文字 +// 2. 输出 optionalNote 和 finalComment 分别是什么 +// 3. 用 for 循环读取 records +// 4. 如果遇到 undefined 或 null,就 break +// 5. 输出 finishedRecords diff --git a/03-javascript-core/16-final-review/README.md b/03-javascript-core/16-final-review/README.md new file mode 100644 index 0000000..cb19756 --- /dev/null +++ b/03-javascript-core/16-final-review/README.md @@ -0,0 +1,47 @@ +# 练习 16:总复习 + +## 目标 + +把基础练习和补充练习里的关键知识点串起来,完成一个真正的总复盘脚本。 + +## 项目名称 + +学习营总复盘器 + +## 你要练什么 + +- 对象和对象方法 +- `this` +- 数组高阶函数 +- `switch` +- `break` +- `undefined` / `null` +- 引用类型 +- 函数封装 + +## 任务 + +请完成一个控制台版“学习营总复盘器”,要求至少包含: + +- 一个带方法的 `reviewer` 对象 +- 一个 `lessons` 数组 +- 一个用 `switch` 输出阶段说明的函数 +- 一个用 `for + break` 清洗有效数据的过程 +- 至少两个数组高阶函数 +- 对 `undefined` 和 `null` 的判断 +- 一段对象引用变化的观察代码 +- 最终输出标题、有效课程、平均分、完成状态 + +## 自检标准 + +- 是否把数据、判断、统计拆成了清晰步骤 +- 是否正确使用了 `this` +- 是否知道什么时候该 `break` +- 是否能区分 `undefined` 和 `null` +- 是否能看出对象引用共享带来的变化 +- 输出信息是否完整、可读 + +## 文件 + +- [starter.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/16-final-review/starter.js) +- [answer.js](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/16-final-review/answer.js) diff --git a/03-javascript-core/16-final-review/answer.js b/03-javascript-core/16-final-review/answer.js new file mode 100644 index 0000000..e481c0f --- /dev/null +++ b/03-javascript-core/16-final-review/answer.js @@ -0,0 +1,70 @@ +const reviewer = { + name: "林晨", + stage: "final-review", + showTitle() { + console.log(`${this.name} 的学习营总复盘`); + }, +}; + +const lessons = [ + { title: "变量", score: 80, finished: true }, + { title: "闭包", score: 92, finished: true }, + { title: "this", score: 87, finished: true }, + { title: "补漏练习", score: null, finished: false }, + { title: "综合回顾", score: 95, finished: true }, +]; + +let mentorNote; +const reviewComment = null; + +function getStageText(stage) { + switch (stage) { + case "basic": + return "基础阶段"; + case "advanced": + return "补充阶段"; + case "final-review": + return "总复习阶段"; + default: + return "未知阶段"; + } +} + +reviewer.showTitle(); +console.log("阶段说明:", getStageText(reviewer.stage)); +console.log("mentorNote 是否为 undefined:", mentorNote === undefined); +console.log("reviewComment 是否为 null:", reviewComment === null); + +const validLessons = []; + +for (let index = 0; index < lessons.length; index += 1) { + const lesson = lessons[index]; + + if (lesson.score === undefined || lesson.score === null) { + console.log(`在《${lesson.title}》处遇到空成绩,停止读取后续项目。`); + break; + } + + validLessons.push(lesson); +} + +const lessonTitles = validLessons.map(function (lesson) { + return lesson.title; +}); + +const averageScore = + validLessons.reduce(function (total, lesson) { + return total + lesson.score; + }, 0) / validLessons.length; + +const allFinished = validLessons.every(function (lesson) { + return lesson.finished === true; +}); + +const reviewerAlias = reviewer; +reviewerAlias.stage = "advanced"; + +console.log("引用修改后的 reviewer.stage:", reviewer.stage); +console.log("有效课程:", lessonTitles.join("、")); +console.log("平均分:", averageScore); +console.log("是否全部完成:", allFinished); diff --git a/03-javascript-core/16-final-review/starter.js b/03-javascript-core/16-final-review/starter.js new file mode 100644 index 0000000..28dae11 --- /dev/null +++ b/03-javascript-core/16-final-review/starter.js @@ -0,0 +1,30 @@ +const reviewer = { + name: "林晨", + stage: "final-review", + showTitle() { + // 输出总复盘标题 + }, +}; + +const lessons = [ + { title: "变量", score: 80, finished: true }, + { title: "闭包", score: 92, finished: true }, + { title: "this", score: 87, finished: true }, + { title: "补漏练习", score: null, finished: false }, + { title: "综合回顾", score: 95, finished: true }, +]; + +let mentorNote; +const reviewComment = null; + +function getStageText(stage) { + // 用 switch 返回阶段说明 +} + +// 任务: +// 1. 调用 reviewer.showTitle() +// 2. 输出 mentorNote 和 reviewComment 的区别 +// 3. 用 for + break 提取 lessons 中 score 有效的项目 +// 4. 用高阶函数统计课程标题、完成状态和平均分 +// 5. 创建 reviewerAlias 指向 reviewer,修改 stage,观察原对象是否变化 +// 6. 输出最终结果 diff --git a/03-javascript-core/README.md b/03-javascript-core/README.md new file mode 100644 index 0000000..d029b07 --- /dev/null +++ b/03-javascript-core/README.md @@ -0,0 +1,197 @@ +# JavaScript Core + +这部分只解决一个问题:你能不能用 JavaScript 把数据、条件、循环和函数这些基础逻辑写清楚。 + +## 学完后你应该掌握 + +- 变量声明和赋值 +- `var`、`let`、`const` 的区别 +- 常见数据类型 +- 运算符和条件判断 +- `if` / `else` / `switch` 的基本使用 +- `for` / `while` 的循环写法 +- 函数声明、参数和返回值 +- 数组和对象的基础操作 +- `this` 的基础指向 +- 常见内置方法和数组高阶函数 +- `switch`、`break`、`undefined`、`null` 的常见场景 +- 内存、执行顺序和引用关系的初步理解 +- 作用域和闭包的基本概念 +- 如何把几个基础知识点组合成一个小程序 + +## JavaScript 是什么 + +JavaScript 负责的是页面和程序里的逻辑。 + +它回答的是: + +- 数据怎么保存 +- 条件怎么判断 +- 重复逻辑怎么执行 +- 功能怎么封装 +- 多个数据怎么组织 + +如果 HTML 是骨架,CSS 是外观,那么 JavaScript 就是行为和思考过程。 + +## 必须建立的 5 个核心意识 + +### 1. 先想输入、过程、输出 + +写逻辑前先问自己: + +- 输入是什么 +- 中间要做什么处理 +- 最后要输出什么结果 + +### 2. 变量不是“魔法盒子”,而是有意义的命名 + +```js +const userName = "小周"; +const completedCount = 5; +``` + +变量名应该表达含义,而不是只写 `a`、`b`、`x`。 + +### 3. 条件和循环是在表达规则 + +- 条件:满足什么情况就做什么 +- 循环:同一件事要重复做多少次 + +### 4. 函数是为了复用,不是为了凑语法 + +当一段逻辑会重复出现,或者本身是一个完整动作时,就应该考虑封装成函数。 + +### 5. 数据结构决定你怎么写逻辑 + +- 单个值:用变量 +- 一组同类值:用数组 +- 一个事物的多个属性:用对象 + +## 高频概念速记 + +### 变量 + +- `var` +- `const` +- `let` + +### 数据类型 + +- `string` +- `number` +- `boolean` +- `undefined` +- `null` +- `object` + +### 条件和比较 + +- `if` +- `else` +- `switch` +- `===` +- `!==` +- `>` +- `<` +- `&&` +- `||` +- `!` + +### 循环 + +- `for` +- `while` +- `break` +- `continue` + +### 函数 + +- `function` +- `return` +- 参数 +- 返回值 +- `this` + +### 数据结构 + +- `Array` +- `Object` + +### 常见数组方法 + +- `map` +- `filter` +- `reduce` +- `find` +- `some` +- `every` + +## 学习顺序 + +1. 变量和输出 +2. 数据类型 +3. 运算符和条件 +4. 循环 +5. 函数 +6. 数组 +7. 对象 +8. 常见方法 +9. 作用域和闭包 +10. 基础阶段综合练习 +11. `var` 和作用域差异 +12. `this` +13. 数组高阶函数 +14. 内存和执行过程 +15. `switch`、`break` 和空值判断 +16. 总复习 + +## 练习目录 + +- [01-variables-and-console/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/01-variables-and-console/README.md) +- [02-data-types-and-conversion/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/02-data-types-and-conversion/README.md) +- [03-operators-and-conditions/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/03-operators-and-conditions/README.md) +- [04-loops/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/04-loops/README.md) +- [05-functions/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/05-functions/README.md) +- [06-arrays/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/06-arrays/README.md) +- [07-objects/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/07-objects/README.md) +- [08-built-in-methods/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/08-built-in-methods/README.md) +- [09-scope-and-closure/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/09-scope-and-closure/README.md) +- [10-final-mini-app/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/10-final-mini-app/README.md) +- [11-var-and-scope/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/11-var-and-scope/README.md) +- [12-this-keyword/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/12-this-keyword/README.md) +- [13-array-high-order-methods/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/13-array-high-order-methods/README.md) +- [14-memory-and-execution/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/14-memory-and-execution/README.md) +- [15-switch-break-and-empty-values/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/15-switch-break-and-empty-values/README.md) +- [16-final-review/README.md](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/16-final-review/README.md) + +## 过关标准 + +如果你能独立做到下面这些,就说明你的 JavaScript 基础已经立住了: + +- 能写出清晰的变量声明和赋值 +- 能分清常见数据类型,并知道什么时候需要类型转换 +- 能写条件判断处理不同分支 +- 能用循环处理一组数据 +- 能把逻辑封装成函数并返回结果 +- 能读写数组和对象里的数据 +- 能理解 `var`、`let`、`const` 的常见区别 +- 能判断普通函数、对象方法、箭头函数里的 `this` 常见差异 +- 能使用几个常见字符串、数组方法和高阶函数 +- 能区分 `undefined` 和 `null`,并在合适位置使用 `switch`、`break` +- 能理解基础的值传递、引用传递和执行顺序 +- 能理解局部作用域和闭包的基本效果 +- 能独立写出一个小型控制台程序 + +## 学习建议 + +- 每个练习先自己写,再看答案 +- 先保证逻辑正确,再考虑写得更短 +- 遇到报错先读报错信息,不要急着猜 +- 多用 `console.log()` 观察变量变化 + +## 运行调试 + +- 可以直接双击打开 [runner.html](/Users/lijiaqing/home/wwwroot/front-end-example/03-javascript-core/runner.html) +- 在页面里选择练习目录和 `starter.js` / `answer.js` +- 点击“运行代码”查看 `console.log()` 输出和报错 +- 改完某个 `.js` 文件后,回到运行器重新点击一次“运行代码”即可 diff --git a/03-javascript-core/runner.html b/03-javascript-core/runner.html new file mode 100644 index 0000000..e891767 --- /dev/null +++ b/03-javascript-core/runner.html @@ -0,0 +1,635 @@ + + + + + + JavaScript Core Runner + + + +
+
+
03-javascript-core
+

JavaScript 练习运行器

+

+ 这个页面可以直接双击打开。选择练习和版本后,点击“运行代码”就会在下方看到 + console.log() 输出、警告和报错。 +

+
+ +
+ + +
+
+
+

控制台输出

+

这里会显示 console.log()console.warn()console.error() 和运行时错误。

+
+
等待运行
+
+ +
+ +
+
调试建议:卡住时多打印变量,先看每一步结果,再改逻辑。
+
断点方式:你可以在对应的 .js 文件里加上 debugger;,然后重新运行。
+
适用范围:当前运行器适合这套纯 JavaScript 控制台练习,不依赖 Node。
+
+
+
+
+ + + + + + diff --git a/README.md b/README.md index d55dc63..f9de029 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,22 @@ - `starter.html` / `starter.css` 起始代码 - `answer.html` / `answer.css` 参考答案 -两部分现在都已经补充到“核心主线 + 常见细分知识点”。 +现在也已经整理好 `03-javascript-core`,里面包含: + +- JavaScript 核心讲义 +- 分阶段练习 +- `starter.js` 起始代码 +- `answer.js` 参考答案 + +前三部分现在都已经补充到“核心主线 + 常见细分知识点”。 ## 使用方式 1. 先阅读 [01-html-structure/README.md](/Volumes/Macintosh HD 1/home/front-end-example/01-html-structure/README.md) 2. 再阅读 [02-css-layout/README.md](/Volumes/Macintosh HD 1/home/front-end-example/02-css-layout/README.md) -3. 按顺序完成每个练习目录 -4. 先写 `starter.html` 或 `starter.css` -5. 写完后再对照答案文件 +3. 再阅读 [03-javascript-core/README.md](/Volumes/Macintosh HD 1/home/front-end-example/03-javascript-core/README.md) +4. 按顺序完成每个练习目录 +5. 先写 `starter.html`、`starter.css` 或 `starter.js` +6. 写完后再对照答案文件 -如果你后面要继续学其他知识点,我可以按同样结构继续给你补 `03-javascript-core`、`04-dom-events-async` 等目录。 +如果你后面要继续学其他知识点,我可以按同样结构继续给你补 `04-dom-events-async`、`05-typescript` 等目录。