第三部分:赋予网页灵魂 —— JavaScript


我们已经用 HTML 搭建了网页的"骨架",用 CSS 给它化了"妆容",现在,是时候让它真正"活"起来了!JavaScript 就是负责这项任务的魔法师。

如果说 HTML 是房子的结构,CSS 是装修,那么 JavaScript 就像是给房子通上了电,安装了各种智能家居系统。它能让灯(页面元素)根据开关(用户点击)亮灭,能让电视(数据显示区域)播放不同的节目(从服务器获取数据),能让门禁(表单)验证访客身份。总之,JavaScript 负责处理网页的交互逻辑和动态行为。

1. JavaScript 基础语法:电线、开关和仪表盘

JavaScript 是一种脚本语言,主要运行在用户的浏览器(客户端)中,用来实现网页的动态交互。

引入 JS:

  • 内联: <script> alert('Hello!'); </script> (不推荐,除非极简短)
  • 外部: <script src="myscript.js"></script> (推荐!放在 <body> 结束前)。这就像把复杂的电路图纸单独存放。

注释: 解释代码用途,方便自己和他人阅读。

变量: 存储数据的容器,就像电路中的各种开关、传感器、存储器。

  • var: (旧版) 有函数作用域和变量提升问题,尽量避免使用。
  • let: 声明块级作用域的变量,值可以被修改。推荐用于需要重新赋值的变量。
  • const: 声明块级作用域的常量,值在声明后不能被重新赋值(但如果值是对象或数组,其内部内容可修改)。推荐优先使用 const,除非明确需要重新赋值。

数据类型: JavaScript 能处理不同类型的数据,就像电器有不同的规格。

  • 基本类型: 存储简单值。String (文本), Number (数字), Boolean (真/假), Null (空值), Undefined (未定义), Symbol (唯一标识符), BigInt (大整数)。
  • 引用类型: Object (对象,包含数组、函数等复杂结构)。

console.log(): 开发者的"仪表盘",可以在浏览器开发者工具的 Console 面板输出信息,是调试代码的最基本、最重要的工具。

1.1 小例子:声明不同类型的变量并在控制台输出

创建01.js

// 01.js

// 使用 let 声明可变变量
let message = "你好,JavaScript!"; // String 类型
let currentYear = 2025;           // Number 类型
let isLearning = true;            // Boolean 类型

// 使用 const 声明常量
const PI = 3.14159;               // Number 类型常量
const SITE_NAME = "我的学习网站"; // String 类型常量

// 特殊类型
let user = null;                  // Null 类型
let undefinedVar;                 // Undefined 类型

// 在控制台输出变量值
console.log(message);
console.log("当前年份:", currentYear); // 可以输出多个值
console.log("正在学习中?", isLearning);
console.log("圆周率:", PI);
console.log("网站名称:", SITE_NAME);
console.log("用户信息:", user);
console.log("未定义变量:", undefinedVar);

// 修改 let 声明的变量
message = "JavaScript 基础入门";
console.log("更新后的消息:", message);

// 尝试修改 const 声明的常量会报错 (取消注释会看到错误)
// PI = 3.14;

创建01.html

<!DOCTYPE html>
<html>
<head> <title>JS 基础</title> </head>
<body>
  <h1>查看浏览器控制台</h1>
  <script src="myscript.js"></script>
</body>
</html>

为了看到输出,我们可以在trae的对话窗口输入预览这个文件
在这里插入图片描述
他会自动识别到意图,选择合适的命令,现在点击一下预览
在这里插入图片描述
我们的内容页面需要一定的样式,你可以把新写的这个html和一个已经开发好的拖入右侧窗口,告诉trae让他仿写一下
在这里插入图片描述
代码改写后点击全部接受,然后再点击预览
在这里插入图片描述
然后回到我们的主文件,增加我们的内容页的链接,后续就可以按tab键,trae就会自动识别意图做改写
在这里插入图片描述
改好主文件后,打开我们的第一节内容
在这里插入图片描述
点击浏览器的三个点,选择开发者工具
在这里插入图片描述
可以看到控制台输出了具体的内容
在这里插入图片描述

1.2 练习

  1. 编写代码,交换两个变量的值(例如 let a = 5; let b = 10; 交换后 a 为 10,b 为 5)。
  2. 声明变量分别存储你的姓名(String)、年龄(Number)、是否已工作(Boolean),并在控制台输出。

2 运算符与表达式:连接电路与计算逻辑

运算符就像电路中的连接器和逻辑门,用于对数据(变量)进行计算、比较和组合。表达式是由变量、常量和运算符组成的式子,会产生一个结果。

  • 算术: 进行数学计算。+ 也可用于字符串拼接。
  • 赋值: 给变量赋值。+= 等是简写形式 (如 x += 5 等价于 x = x + 5)。
  • 比较: 比较两个值,返回 true 或 false。强烈推荐使用 === 和 !== (全等/不全等),它们不仅比较值,还比较数据类型,可以避免一些隐式类型转换带来的坑。== 只比较值,会进行类型转换 (如 5 == ‘5’ 为 true,但 5 === ‘5’ 为 false)。
  • 逻辑: 组合布尔值。&& (都为真才为真), || (有一个为真就为真), ! (取反)。
  • 三元: if…else 的简洁写法,适用于简单的条件赋值。

2.1 小例子:计算圆的面积,判断数字是否为偶数

// 计算圆面积
const radius = 5;
const area = Math.PI * radius ** 2; // Math.PI 是内置的圆周率,** 是幂运算符
console.log(`半径为 ${radius} 的圆面积是: ${area}`); // 使用模板字符串

// 判断偶数
let numberToCheck = 10;
let isEven = numberToCheck % 2 === 0; // 取模运算,余数为 0 则是偶数
console.log(`${numberToCheck} 是偶数吗? ${isEven}`);

numberToCheck = 7;
isEven = numberToCheck % 2 === 0;
console.log(`${numberToCheck} 是偶数吗? ${isEven}`);

// 比较运算符示例
console.log("5 == '5'?", 5 == '5');   // true (值相等,类型不同但会转换)
console.log("5 === '5'?", 5 === '5'); // false (类型不同)
console.log("5 !== '5'?", 5 !== '5'); // true

// 逻辑运算符示例
let age = 25;
let hasLicense = true;
let canDrive = age >= 18 && hasLicense; // 年龄大于等于18 且 有驾照
console.log("可以开车吗?", canDrive);

// 三元运算符示例
let score = 75;
let result = score >= 60 ? "及格" : "不及格";
console.log(`分数 ${score}, 结果: ${result}`);

运行后的效果
在这里插入图片描述

2.2 练习

编写一个简单的身体质量指数 (BMI) 计算器逻辑。需要两个变量:身高(米)和体重(公斤),计算公式为 BMI = 体重 / (身高 * 身高),并将结果输出到控制台。

3 流程控制语句:设定程序的运行路径

流程控制就像设定智能家居的自动化规则:“如果 (if) 温度低于 20 度,就打开暖气,否则 (else) 关闭”;“重复执行 (for/while) 打扫任务,直到电量耗尽”。

条件语句: 根据不同的条件执行不同的代码块。if 用于单一条件,if…else 用于两种情况,if…else if…else 用于多种条件判断。switch 适用于基于一个表达式的多个固定值进行判断。

循环语句: 重复执行代码块。

  • for: 最常用,适用于已知循环次数或有明确计数器的情况。
  • while: 先判断条件,条件为真则执行循环体,适用于循环次数不确定的情况。
  • do…while: 先执行一次循环体,再判断条件,至少执行一次。
  • for…in: 遍历对象的可枚举属性名 (key)。
  • for…of: 遍历可迭代对象 (如 Array, String, Map, Set) 的值 (value)。推荐用于遍历数组。

3.1 判断成绩等级,打印九九乘法表

// 判断成绩等级
let grade = 85;
if (grade >= 90) {
  console.log("优秀");
} else if (grade >= 80) {
  console.log("良好");
} else if (grade >= 60) {
  console.log("及格");
} else {
  console.log("不及格");
}

// switch 示例 (判断星期几)
let day = new Date().getDay(); // 获取当前星期几 (0=周日, 1=周一, ...)
let dayName;
switch (day) {
  case 0: dayName = "星期日"; break;
  case 1: dayName = "星期一"; break;
  case 2: dayName = "星期二"; break;
  // ... 其他 case
  case 6: dayName = "星期六"; break;
  default: dayName = "未知";
}
console.log(`今天是: ${dayName}`);

// 打印九九乘法表 (for 循环嵌套)
console.log("九九乘法表:");
for (let i = 1; i <= 9; i++) {
  let row = '';
  for (let j = 1; j <= i; j++) {
    row += `${j} * ${i} = ${i * j}\t`; // \t 是制表符,用于对齐
  }
  console.log(row);
}

// for...of 遍历数组
const colors = ['red', 'green', 'blue'];
console.log("遍历颜色数组:");
for (const color of colors) {
  console.log(color);
}

运行后的效果
在这里插入图片描述

3.2 练习

编写代码,找出 1 到 100 之间所有的质数(只能被 1 和自身整除的大于 1 的整数)并输出到控制台。

4 函数:封装指令的工具箱

函数就像工具箱里的特定工具(如"计算面积工具"、“发送问候工具”)。它将一系列操作打包封装起来,给它一个名字,需要时就可以通过名字调用它,可以传递参数(原材料)给它,它也可以返回结果(成品)。这让代码更有条理、可维护、可复用。

  • 声明 vs 表达式: 声明的函数会被提升(可以在声明前调用),表达式定义的函数则不行。
  • 箭头函数: ES6 引入的更简洁的函数语法,尤其适用于回调函数和匿名函数。它没有自己的 this 绑定(会继承外部作用域的 this)。
  • 参数: 函数接收的输入值。
  • 返回值: 函数执行后输出的结果,使用 return 关键字。如果函数没有 return,默认返回 undefined。
  • 作用域: 变量可访问的范围。全局变量处处可访问,函数内变量只能在函数内访问,let/const 声明的变量还有块级作用域(如 if 或 for 的 {} 内)。
  • 闭包: 一个强大的概念,允许函数"记住"它创建时的环境。简单理解:内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。

4.1 小例子:创建计算两数之和的函数,创建问候用户的函数

// 函数声明
function add(num1, num2) {
  return num1 + num2;
}

// 函数表达式
const greet = function(name) {
  console.log(`你好, ${name}!`);
};

// 箭头函数
const multiply = (a, b) => {
  return a * b;
};
// 如果箭头函数体只有一行且是返回值,可以省略 {} 和 return
const subtract = (a, b) => a - b;

// 调用函数
let sum = add(5, 3);
console.log("5 + 3 =", sum);

greet("张三");

let product = multiply(4, 6);
console.log("4 * 6 =", product);

let difference = subtract(10, 4);
console.log("10 - 4 =", difference);

// 作用域示例
let globalVar = "我是全局变量";
function scopeTest() {
  let functionVar = "我是函数内变量";
  console.log(globalVar); // 可以访问全局变量
  if (true) {
    let blockVar = "我是块级变量";
    console.log(functionVar); // 可以访问函数变量
  }
  // console.log(blockVar); // 在这里访问块级变量会报错
}
scopeTest();
// console.log(functionVar); // 在这里访问函数变量会报错

运行后的效果
在这里插入图片描述

4.2 练习

编写一个名为 isLeapYear 的函数,接收一个年份作为参数,判断该年份是否为闰年(能被 4 整除但不能被 100 整除,或者能被 400 整除),返回 true 或 false。

5 数组 (Array):有序数据的货架

数组就像一个有序的货架,可以按顺序存放多个数据(可以是不同类型)。每个位置都有一个编号(索引,从 0 开始),可以方便地存取、添加、删除和遍历这些数据。JavaScript 提供了极其丰富的数组方法来高效地操作数据。

访问: myArray[0] 访问第一个元素。
修改: myArray[1] = ‘new value’;
常用方法:

  • 增删: push/pop (末尾), unshift/shift (开头), splice (任意位置)。
  • 截取/合并: slice, concat。
  • 查找: indexOf, includes, find, findIndex。
  • 遍历方法 (非常重要): 这些方法通常接收一个回调函数作为参数,对数组每个元素执行该函数。
    • forEach(): 纯粹遍历,不返回值。
    • map(): 对每个元素执行操作,返回一个新的、包含结果的数组。
    • filter(): 根据条件筛选元素,返回一个新的、包含符合条件元素的数组。
    • reduce(): 将数组元素累加或聚合为一个单一的值。

5.1 小例子:管理一个待办事项列表(增删改查)

let todos = ["学习 HTML", "学习 CSS"];

// 添加
todos.push("学习 JavaScript");
todos.unshift("准备开发环境"); // 开头添加
console.log("添加后:", todos);

// 删除
let removedLast = todos.pop(); // 删除最后一个
console.log("删除了:", removedLast);
let removedFirst = todos.shift(); // 删除第一个
console.log("删除了:", removedFirst);
console.log("删除后:", todos);

// 修改 (使用 splice)
// splice(起始索引, 删除数量, 要插入的元素1, 元素2, ...)
todos.splice(1, 1, "深入学习 CSS"); // 替换索引 1 的元素
console.log("修改后:", todos);

// 查找
let jsIndex = todos.indexOf("学习 JavaScript");
console.log("JavaScript 的索引:", jsIndex);
console.log("是否包含 '学习 HTML'?", todos.includes("学习 HTML"));

// 遍历 (forEach)
console.log("待办事项:");
todos.forEach(function(todo, index) {
  console.log(`${index + 1}. ${todo}`);
});

// 映射 (map) - 创建一个包含任务长度的新数组
let todoLengths = todos.map(todo => todo.length);
console.log("任务长度:", todoLengths);

// 过滤 (filter) - 筛选包含 "学习" 的任务
let learningTasks = todos.filter(todo => todo.includes("学习"));
console.log("学习任务:", learningTasks);

运行后的效果
在这里插入图片描述

5.2 练习

  1. 给定一个数字数组,例如 [1, 5, 2, 5, 3, 1, 5],编写代码统计每个数字出现的次数。
  2. 给定一个数字数组,使用 filter 方法筛选出所有的偶数,并返回一个新的数组。

6 对象 (Object):描述事物的属性集合

对象是 JavaScript 中表示复杂事物的方式,它是一组无序的键值对 (key-value pairs) 的集合。键 (key) 是字符串(属性名),值 (value) 可以是任何数据类型(包括其他对象或函数)。就像描述一个"智能灯泡"对象,它有属性(键):color (颜色), brightness (亮度), isOn (是否开启),还有方法(作为值的函数):turnOn() (打开), changeColor() (改变颜色)。

  • 创建: 字面量 {} 是最常用的方式。
  • 访问: 点号 . 用于已知且合法的标识符属性名;方括号 [] 更灵活,可以用于包含特殊字符或变量值的属性名 (myObject[‘property-with-hyphen’] 或 let propName = ‘color’; myObject[propName])。
  • 方法: 对象中的函数被称为方法。
  • this: 在对象方法中,this 通常指向调用这个方法的那个对象实例。this 的指向比较复杂,后续会深入,目前先理解这个基本情况。
  • 遍历: for…in 遍历键名。Object.keys/values/entries 提供更现代的遍历方式。

6.1 小例子:创建一个表示"用户"的对象

// 使用字面量创建对象
const user = {
  firstName: "张",
  lastName: "三",
  age: 30,
  email: "zhangsan@example.com",
  address: { // 值可以是另一个对象
    street: "人民路 123号",
    city: "上海"
  },
  hobbies: ["编码", "阅读", "游戏"], // 值可以是数组
  // 方法
  getFullName: function() {
    // 在方法中,this 指向 user 对象
    return this.firstName + this.lastName;
  },
  // ES6 方法简写
  greet() {
    console.log(`你好,我是 ${this.getFullName()}!`);
  }
};

// 访问属性
console.log("姓:", user.lastName);
console.log("城市:", user.address.city);
console.log("第一个爱好:", user.hobbies[0]);
console.log("邮箱(方括号访问):", user['email']);

// 调用方法
console.log("全名:", user.getFullName());
user.greet();

// 添加新属性
user.isAdmin = false;
console.log("是管理员吗?", user.isAdmin);

// 遍历对象属性 (for...in)
console.log("遍历用户信息:");
for (const key in user) {
  // 检查属性是否是对象自身的,而不是继承来的 (可选但推荐)
  if (Object.hasOwnProperty.call(user, key)) {
    console.log(`${key}: ${user[key]}`); // 注意这里用方括号访问
  }
}

// 使用 Object.keys/values/entries
console.log("所有键:", Object.keys(user));
console.log("所有值:", Object.values(user));
// console.log("所有键值对:", Object.entries(user));

运行后的效果
在这里插入图片描述

6.2 练习

  1. 创建一个表示"书籍"的对象,包含属性 title (书名), author (作者), pages (页数), isRead (是否已读 - Boolean)。
  2. 为该书籍对象添加一个 displayInfo 方法,调用时在控制台打印出书籍的标题和作者。

7 配置MCP

代码写好之后,我们需要发布到github上,我们来配置一个MCP来执行这个操作。切换到Builer with MCP
在这里插入图片描述
添加一下github
在这里插入图片描述
他要求一个token,我们按照要求生成一下
在这里插入图片描述
把token贴入trae里,github就变成了一个可用的状态
在这里插入图片描述
然后在聊天窗口输入发布命令他就会自动检查配置并发布
在这里插入图片描述
我感觉没啥用处,在终端直接打一个命令,用这个还得浪费token

代码地址

https://github.com/wedalowcode/my-first-web-project.git
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

低代码布道师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值