JavaScript 入门:从零开始构建交互式Web体验
欢迎来到奇妙的编程世界!如果你对如何让网页动起来、响应用户的操作感到好奇,那么你来对地方了。JavaScript,通常简称为 JS,就是实现这一切的关键技术。它不仅是现代 Web 开发的基石,也是当今世界上最流行和用途最广泛的编程语言之一。
本篇文章将带你踏上 JavaScript 的学习之旅,从最基础的概念讲起,逐步深入,让你掌握编写简单脚本、与网页互动、控制程序流程的能力。无论你是否有编程经验,只要跟着本文的步伐,耐心实践,你就能迈出成为前端开发者或全栈开发者的坚实第一步。
预计阅读时间: 30-45分钟
目标读者: 对 JavaScript 完全陌生或刚开始接触的初学者
准备好了吗?让我们开始吧!
第一章:JavaScript 是什么?为什么学习它?
在深入学习语法之前,我们先来了解一下 JavaScript 的本质和它的重要性。
1.1 JavaScript 的定义
简单来说,JavaScript 是一种脚本语言,主要用于在用户的浏览器中运行。它的核心能力是让网页变得动态和交互式。
想象一下,你访问一个网站:
* 当你点击一个按钮,页面上的某个区域发生了变化。
* 当你填写表单时,系统会立即检查你的输入是否有效。
* 当你滚动页面时,动画效果出现。
* 当你玩一个简单的网页小游戏。
这些交互和动态效果绝大多数都是通过 JavaScript 实现的。
起初,JavaScript 是为了给网页添加简单的客户端验证和交互而创建的。但随着技术的发展,尤其是 Node.js 的出现,JavaScript 不仅可以在浏览器中运行(客户端),还可以在服务器端运行(后端),甚至可以用于开发移动应用、桌面应用、游戏等等。
1.2 JavaScript 的角色定位
在 Web 开发中,有三个核心技术:
* HTML (HyperText Markup Language): 负责网页的结构和内容,像房子的骨架。
* CSS (Cascading Style Sheets): 负责网页的样式和外观,像房子的装修和装饰。
* JavaScript: 负责网页的行为和交互,像房子的电力、水路和各种智能设备,让房子“活”起来。
这三者紧密协作,共同构建了我们今天看到的丰富多彩的网站。
1.3 为什么学习 JavaScript?
学习 JavaScript 的原因有很多,其中最重要的包括:
- 市场需求巨大: 几乎所有的前端开发职位都要求掌握 JavaScript。随着 Node.js 的普及,全栈开发者(同时掌握前端和后端)也需要 JavaScript。
- 应用范围广泛: 从传统的网站前端,到后端服务器、移动 App (React Native, Ionic)、桌面 App (Electron)、游戏开发 (Phaser)、物联网,JavaScript 无处不在。
- 社区活跃,资源丰富: JavaScript 拥有庞大的开发者社区,这意味着你在学习过程中遇到问题很容易找到答案,并且有海量的库和框架可以利用,极大地提高了开发效率。
- 易于入门: 相比一些更底层的语言,JavaScript 语法相对灵活,上手较快,特别是在浏览器中学习,你可以立即看到代码的效果。
总而言之,掌握 JavaScript 是成为现代软件开发者的必备技能之一。
第二章:准备环境:在哪里写和运行 JavaScript?
学习任何编程语言都需要一个运行环境。对于 JavaScript 而言,最常见的环境就是你的网页浏览器。
2.1 使用浏览器控制台 (Console)
这是学习 JavaScript 最快捷的方式,无需安装任何软件。大多数现代浏览器(如 Chrome, Firefox, Edge, Safari)都内置了开发者工具,其中就包含一个 JavaScript 控制台。
步骤:
1. 打开你的浏览器。
2. 在任何网页上,右键点击,选择“检查”(或“Inspect Element”,“审查元素”等)。
3. 在打开的开发者工具面板中,找到并点击“Console”(控制台)标签页。
4. 在控制台底部的输入区域,你可以直接输入 JavaScript 代码,按 Enter 键执行。
试试看:
在控制台中输入 console.log("你好,世界!");
然后按 Enter。
你应该会看到控制台输出 “你好,世界!”。
console.log()
是一个非常常用的函数,用于在控制台输出信息,这对于调试代码非常有用。
2.2 在 HTML 文件中嵌入 JavaScript
这是将 JavaScript 代码与网页结合的常用方法。你可以通过 <script>
标签将 JavaScript 代码添加到 HTML 文件中。
<script>
标签有两种主要用法:
-
内嵌脚本: 直接将 JavaScript 代码写在
<script>
标签内部。“`html
<!DOCTYPE html>
我的第一个 JS 页面
<h1>欢迎学习 JavaScript</h1> <script> // 这是一段内嵌的 JavaScript 代码 console.log("这段代码在页面加载后运行"); alert("这是一个弹窗!"); // alert() 会弹出一个对话框 </script> <p>上面的脚本运行了。</p>
``
.html` 文件,然后在浏览器中打开它。你会先看到一个弹窗,点击确定后,控制台(如果打开了)会输出一条信息。
将这段代码保存为 -
外部脚本: 将 JavaScript 代码写在一个单独的
.js
文件中,然后在 HTML 文件中使用<script src="...">
标签链接到这个文件。创建一个名为
script.js
的文件:
javascript
// 这是一个外部 JavaScript 文件 (script.js)
console.log("这是来自外部文件的信息!");修改你的 HTML 文件:
“`html
<!DOCTYPE html>
使用外部 JS 文件
<h1>加载外部 JavaScript</h1> <p>看看控制台有什么输出。</p> <!-- 通过 src 属性链接到外部 .js 文件 --> <script src="script.js"></script>
`` 将这两个文件放在同一个文件夹中,然后打开 HTML 文件。浏览器会加载并执行
script.js` 文件中的代码。
<script>
标签的放置位置:
- 传统上,人们喜欢将
<script>
标签放在<head>
中。但这可能会导致页面加载变慢,因为浏览器会先下载和执行脚本,然后才渲染页面内容。如果脚本需要操作页面元素,而这些元素此时还未加载,就会出错。 - 推荐做法: 将
<script>
标签放在<body>
结束标签 (</body>
) 之前。这样可以确保在脚本执行时,页面上的 HTML 元素已经加载完毕,脚本可以安全地操作它们。 - 现代方法: 在
<head>
中使用defer
或async
属性。defer
: 脚本会在 HTML 解析完成后按顺序执行。不阻塞 HTML 解析。async
: 脚本会在下载完成后立即执行,不保证执行顺序,也不阻塞 HTML 解析。适用于不依赖其他脚本或 DOMContentLoaded 事件的独立脚本。 对于初学者,先将<script>
放在<body>
结束前是最简单和安全的选择。
2.3 使用 Node.js (了解即可)
除了浏览器,你还可以在服务器上运行 JavaScript,这需要安装 Node.js 环境。Node.js 是一个 JavaScript 运行时,它让 JavaScript 能够脱离浏览器独立运行。这使得 JavaScript 可以用于构建后端服务、命令行工具等。
对于入门学习,主要关注浏览器环境就足够了。
第三章:JavaScript 基础语法
就像学习任何语言一样,我们首先需要了解 JavaScript 的基本书写规则。
3.1 语句 (Statements)
JavaScript 代码由一系列的语句组成。每个语句执行一个特定的任务。
javascript
console.log("这是一个语句"); // 这是一个输出语句
let x = 10; // 这是一个变量声明和赋值语句
let y = x + 5; // 这是一个计算并赋值的语句
3.2 分号 (Semicolons)
在 JavaScript 中,语句通常以分号 ;
结尾。分号表示一个语句的结束。
javascript
console.log("语句一");
console.log("语句二");
JavaScript 引擎在大多数情况下可以自动推断出分号的位置(这被称为自动分号插入 Automatic Semicolon Insertion – ASI)。所以,即使你省略了分号,代码也可能正常工作。
javascript
console.log("语句一")
console.log("语句二") // 这也能工作
建议: 虽然分号不是强制性的,但为了代码的可读性、避免潜在的 ASI 带来的歧义以及遵循业界规范,推荐始终在语句末尾使用分号,特别是在一行写多个语句时。
3.3 注释 (Comments)
注释是写在代码中,用于解释代码用途或功能的文本。JavaScript 引擎会忽略注释,它们只对开发者有帮助。
-
单行注释: 以
//
开头,直到行尾。javascript let age = 30; // 定义一个年龄变量
-
多行注释: 以
/*
开头,以*/
结尾,可以跨越多行。javascript /* 这是一个多行注释 用于解释一段较长的代码块 或者临时禁用一块代码 */ let name = "Alice";
善用注释: 好的注释能够帮助你和其他开发者更好地理解代码,特别是在代码变得复杂时。
3.4 区分大小写 (Case Sensitivity)
JavaScript 是区分大小写的。这意味着 myVariable
和 myvariable
是两个不同的变量名。关键字、函数名和变量名都必须严格匹配大小写。
javascript
let myVariable = 10;
// console.log(MyVariable); // 这会导致错误,因为大小写不匹配
console.log(myVariable); // 正确
内置的函数和关键字也是区分大小写的,例如 console.log
必须是小写,function
必须是小写等等。
3.5 代码块 (Code Blocks)
使用花括号 {}
将多个语句组织在一起,形成一个代码块。代码块通常用于控制结构(如条件语句、循环)和函数中。
javascript
if (true) {
// 这是一个代码块
let message = "Hello";
console.log(message);
}
第四章:变量与数据类型
变量是用于存储数据的“容器”。在 JavaScript 中,你可以声明变量并给它们赋值。
4.1 声明变量 (let
, const
, var
)
在现代 JavaScript 中,主要使用 let
和 const
来声明变量。
-
let
: 声明一个块作用域的局部变量,其值可以被重新赋值。“`javascript let age = 25; console.log(age); // 输出 25
age = 26; // 重新赋值 console.log(age); // 输出 26
// let 不能在同一作用域内重复声明同一个变量 // let age = 27; // 会导致错误 “`
-
const
: 声明一个块作用域的常量,其值在声明后不能被重新赋值。“`javascript const PI = 3.14159; console.log(PI); // 输出 3.14159
// PI = 3.14; // 会导致错误:尝试给常量重新赋值
// const 必须在声明时立即赋值 // const URL; // 错误:常量没有初始值 const URL = “http://example.com”; // 正确
`` 注意:对于对象或数组等引用类型,
const保证的是变量指向的内存地址不变,而不是变量内部存储的数据不变。也就是说,你可以修改
const` 声明的对象或数组的属性或元素,但不能将它指向一个新的对象或数组。 -
var
: 这是在let
和const
出现之前(ES6 标准前)声明变量的唯一方式。var
声明的变量是函数作用域或全局作用域的,且存在变量提升 (hoisting) 等特性,可能导致一些意料之外的行为。在现代 JavaScript 开发中,不推荐使用var
,优先使用let
和const
。“`javascript var greeting = “Hello”; console.log(greeting); // 输出 Hello
greeting = “Hi”; // 可以重新赋值 console.log(greeting); // 输出 Hi
var greeting = “Bonjour”; // 可以重复声明,这是 var 的一个“特点” console.log(greeting); // 输出 Bonjour “`
总结:
* 如果变量的值在程序运行过程中不会改变,使用 const
。
* 如果变量的值在程序运行过程中会改变,使用 let
。
* 避免使用 var
。
4.2 变量命名规则
- 变量名可以包含字母、数字、下划线
_
和美元符号$
。 - 变量名不能以数字开头。
- 变量名不能使用 JavaScript 的保留字(如
if
,for
,function
,let
,const
等)。 - 变量名是区分大小写的。
- 避免使用中文或其他特殊字符作为变量名(虽然技术上允许,但不利于跨平台和协作)。
- 推荐使用驼峰命名法 (camelCase):第一个单词小写,后面每个单词的首字母大写,例如
myFirstName
,totalAmount
。
4.3 数据类型 (Data Types)
JavaScript 是一种动态类型语言。这意味着你声明变量时不需要指定它的数据类型,变量的数据类型是在运行时由赋给它的值决定的,并且可以随时改变(对于 let
和 var
声明的变量)。
JavaScript 的数据类型可以分为两大类:原始类型 (Primitive Types) 和 对象类型 (Object Type)。
4.3.1 原始类型 (共7种)
-
String (字符串): 表示文本数据。可以用单引号
' '
、双引号" "
或反引号`
包裹。javascript let name = "Alice"; let message = 'Hello World'; let greeting = `你好, ${name}!`; // 反引号支持模板字符串,可以在字符串中嵌入变量 console.log(greeting); // 输出 你好, Alice!
-
Number (数字): 表示数值,包括整数和浮点数。
javascript let age = 30; // 整数 let price = 19.99; // 浮点数 let bigNumber = 1e6; // 科学计数法 1 * 10^6 = 1000000
注意:JavaScript 中没有单独的整数类型,所有数字都是双精度浮点数。 -
Boolean (布尔值): 表示真或假,只有两个可能的值:
true
和false
。javascript let isLogged = true; let hasPermission = false;
布尔值常用于控制程序流程。 -
Null (空): 表示一个有意为之的空值。表示变量没有指向任何对象。
javascript let car = null; // 明确表示 car 变量当前没有值
注意:typeof null
的结果是"object"
,这是一个历史遗留的 bug,不要误认为null
是对象。 -
Undefined (未定义): 表示变量已声明但没有赋值。或者函数没有返回任何值时,默认返回
undefined
。“`javascript let city; // 声明了,但没有赋值,默认为 undefined console.log(city); // 输出 undefined
let result = myFunction(); // 如果 myFunction 没有 return 语句,result 就是 undefined “`
-
Symbol (符号): 在 ES6 中引入,表示独一无二的值。常用于对象属性名,确保属性名不冲突。对初学者来说,这不是必须立即掌握的概念。
javascript const id = Symbol('id'); const anotherId = Symbol('id'); console.log(id === anotherId); // 输出 false
-
BigInt (大整数): 在 ES11 中引入,用于表示任意精度的整数。由于 JavaScript 的 Number 类型有最大安全整数限制 (2^53 – 1),BigInt 可以处理更大的整数。在数字后加上
n
表示 BigInt。对初学者来说,也不是必须立即掌握的概念。javascript const bigNum = 123456789012345678901234567890n;
4.3.2 对象类型 (Object Type)
除了原始类型,JavaScript 中其他所有值都是对象。这包括:
* Object (对象): 无序的键值对集合。
* Array (数组): 有序的数据集合。
* Function (函数): 可执行的代码块。
* 其他内置对象,如 Date
, RegExp
, Map
, Set
等。
我们将在后面的章节中详细介绍对象、数组和函数。
4.3.3 使用 typeof
检查数据类型
你可以使用 typeof
运算符来检查一个变量或值的数据类型。
javascript
console.log(typeof "Hello"); // 输出 "string"
console.log(typeof 123); // 输出 "number"
console.log(typeof true); // 输出 "boolean"
console.log(typeof null); // 输出 "object" (历史遗留问题)
console.log(typeof undefined); // 输出 "undefined"
console.log(typeof {}); // 输出 "object"
console.log(typeof []); // 输出 "object" (数组也是对象)
console.log(typeof function(){}); // 输出 "function" (函数也是一种特殊的对象)
console.log(typeof Symbol('sym')); // 输出 "symbol"
console.log(typeof 123n); // 输出 "bigint"
第五章:运算符 (Operators)
运算符用于对变量或值执行操作。JavaScript 提供了多种类型的运算符。
5.1 算术运算符 (Arithmetic Operators)
用于执行数学计算:
* +
加法
* -
减法
* *
乘法
* /
除法
* %
取模(求余数)
* **
幂(ES7 引入,x ** y
表示 x 的 y 次方)
* ++
自增(将变量加 1)
* --
自减(将变量减 1)
“`javascript let a = 10; let 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 (10 除以 3 余 1) console.log(a ** b); // 1000 (10的3次方)
let count = 0; count++; // count 变为 1 console.log(count); // 1 count–; // count 变为 0 console.log(count); // 0 “`
注意:
* +
运算符在用于字符串时,是字符串连接。
javascript
console.log("Hello" + " " + "World"); // 输出 "Hello World"
console.log("Result: " + (a + b)); // 输出 "Result: 13"
* 如果 +
运算符的操作数中有一个是字符串,另一个会被转换为字符串进行连接。
javascript
console.log("The answer is " + 42); // 输出 "The answer is 42"
5.2 赋值运算符 (Assignment Operators)
用于给变量赋值:
* =
简单的赋值
* +=
, -=
, *=
, /=
, %=
, **=
复合赋值(将算术运算和赋值结合)
“`javascript let x = 5; // x = 5
x += 3; // 等价于 x = x + 3; x 变为 8 console.log(x); // 8
x *= 2; // 等价于 x = x * 2; x 变为 16 console.log(x); // 16
x /= 4; // 等价于 x = x / 4; x 变为 4 console.log(x); // 4 “`
5.3 比较运算符 (Comparison Operators)
用于比较两个值,返回布尔值 (true
或 false
):
* ==
等于(只比较值,不比较类型,可能存在类型转换)
* ===
严格等于(值和类型都必须相等)
* !=
不等于(只比较值)
* !==
严格不等于(值或类型不相等)
* >
大于
* <
小于
* >=
大于或等于
* <=
小于或等于
javascript
console.log(5 == "5"); // true (值相等,虽然类型不同,== 会进行类型转换)
console.log(5 === "5"); // false (值相等但类型不同,=== 不会进行类型转换)
console.log(5 != "5"); // false
console.log(5 !== "5"); // true
console.log(10 > 5); // true
console.log(10 <= 5); // false
强烈建议: 在进行相等性比较时,优先使用严格相等运算符 ===
和严格不等于运算符 !==
,以避免隐式类型转换带来的困惑和潜在错误。
5.4 逻辑运算符 (Logical Operators)
用于组合布尔表达式:
* &&
逻辑与 (AND):如果两个操作数都为 true,则结果为 true。
* ||
逻辑或 (OR):如果两个操作数中至少有一个为 true,则结果为 true。
* !
逻辑非 (NOT):反转操作数的布尔值。
“`javascript let isAdult = true; let isStudent = false;
console.log(isAdult && isStudent); // false (true && false) console.log(isAdult || isStudent); // true (true || false) console.log(!isAdult); // false (!true) “`
短路评估 (Short-circuit Evaluation):
* &&
: 如果第一个操作数为 false,则不会评估第二个操作数,直接返回第一个操作数的值。
* ||
: 如果第一个操作数为 true,则不会评估第二个操作数,直接返回第一个操作数的值。
这个特性在给变量设置默认值时很有用: “`javascript let userDefinedColor = “”; // 用户没有设置颜色 let defaultColor = “blue”; let finalColor = userDefinedColor || defaultColor; // “” 是 falsy 值,所以返回 defaultColor console.log(finalColor); // “blue”
userDefinedColor = “red”; finalColor = userDefinedColor || defaultColor; // “red” 是 truthy 值,所以返回 userDefinedColor console.log(finalColor); // “red” “`
5.5 三元运算符 (Conditional Ternary Operator)
这是唯一的需要三个操作数的运算符,提供了一种简洁的条件判断方式。
条件 ? 值1 : 值2
如果 条件
为 true,则返回 值1
;否则返回 值2
。
javascript
let age = 18;
let status = (age >= 18) ? "Adult" : "Minor";
console.log(status); // 输出 "Adult"
第六章:控制流程:让代码“思考”
控制流程语句用于决定代码执行的顺序,让程序可以根据条件做出不同的选择或重复执行某些任务。
6.1 条件语句 (Conditional Statements)
根据条件是否为 true 来执行不同的代码块。
6.1.1 if
, else if
, else
这是最常用的条件语句。
“`javascript let temperature = 20;
if (temperature > 30) {
console.log(“天气很热!”);
} else if (temperature > 20) {
console.log(“天气温暖。”);
} else if (temperature > 10) {
console.log(“天气凉爽。”);
} else {
console.log(“天气寒冷。”);
}
// 输出 “天气凉爽。”
``
**注意:** 条件表达式会转换为布尔值。JavaScript 中有一些值被认为是“假值” (falsy),在布尔上下文中会被当作
false,包括:
false,
0,
-0,
“”(空字符串),
null,
undefined,
NaN(Not a Number)。其他所有值(包括空数组
[]和空对象
{}`)都被认为是“真值” (truthy)。
6.1.2 switch
当需要基于一个变量的不同可能值执行不同的代码块时,switch
语句非常有用。
“`javascript let day = “Monday”; let activity;
switch (day) { case “Monday”: activity = “学习编程”; break; // break 语句很重要,用于跳出 switch case “Tuesday”: case “Wednesday”: // 多个 case 可以共用同一段代码 activity = “完成项目”; break; case “Thursday”: case “Friday”: activity = “写文章”; break; default: // 如果没有匹配的 case,执行 default activity = “休息”; }
console.log(“今天要做:” + activity); // 输出 “今天要做:学习编程”
``
**重要:** 总是应该在每个
case的末尾使用
break语句,否则代码会继续执行下一个
case中的语句(称为“穿透” fall-through)。
default不需要
break`,因为它通常是最后一个分支。
6.2 循环语句 (Loop Statements)
循环语句用于重复执行一段代码,直到满足某个条件或遍历完某个集合。
6.2.1 for
循环
for
循环是最常见的循环类型,常用于需要知道循环次数的情况。
javascript
for (let i = 0; i < 5; i++) {
// i 是循环计数器
console.log("循环次数:" + i);
}
// 输出:
// 循环次数:0
// 循环次数:1
// 循环次数:2
// 循环次数:3
// 循环次数:4
for
循环的结构:
* 初始化表达式 (Initialization)
: 在循环开始前执行一次,常用于初始化计数器。
* 条件表达式 (Condition)
: 在每次循环开始前检查,如果为 true 则继续循环,如果为 false 则退出循环。
* 更新表达式 (Update)
: 在每次循环体执行完毕后执行,常用于更新计数器。
6.2.2 while
循环
while
循环在每次循环开始前检查条件,只要条件为 true 就继续执行循环体。适用于不知道具体循环次数,只知道循环结束条件的情况。
javascript
let count = 0;
while (count < 3) {
console.log("While 循环:" + count);
count++; // 务必在循环体内更新条件,否则可能造成无限循环
}
// 输出:
// While 循环:0
// While 循环:1
// While 循环:2
6.2.3 do...while
循环
do...while
循环与 while
循环类似,但它先执行一次循环体,然后再检查条件。这意味着循环体至少会被执行一次。
javascript
let i = 0;
do {
console.log("Do-While 循环:" + i);
i++;
} while (i < 3);
// 输出:
// Do-While 循环:0
// Do-While 循环:1
// Do-While 循环:2
6.2.4 for...in
和 for...of
(了解)
for...in
: 遍历对象的属性名(键)。for...of
: 遍历可迭代对象(如数组、字符串、Map、Set 等)的值。
“`javascript let person = { name: “Alice”, age: 30 }; for (let key in person) { console.log(key + “: ” + person[key]); // 输出 name: Alice, age: 30 }
let numbers = [1, 2, 3, 4, 5]; for (let num of numbers) { console.log(num); // 输出 1, 2, 3, 4, 5 (每个数字一行) } “`
6.2.5 break
和 continue
(了解)
break
: 立即退出当前循环或 switch 语句。continue
: 立即跳过当前循环的剩余部分,进入下一次循环。
javascript
for (let i = 0; i < 10; i++) {
if (i === 5) {
break; // 当 i 等于 5 时,退出循环
}
if (i % 2 === 0) {
continue; // 当 i 是偶数时,跳过当前循环剩余部分,继续下一次循环
}
console.log(i); // 输出 1, 3
}
第七章:函数:代码的复用
函数是一段可重复使用的代码块,用于执行特定的任务。使用函数可以组织代码、提高代码的可读性和可维护性。
7.1 定义函数
主要有两种方式定义函数:
-
函数声明 (Function Declaration):
javascript function greet(name) { // name 是参数 console.log("你好," + name + "!"); }
-
函数表达式 (Function Expression): 将一个匿名函数赋值给一个变量。
javascript const greet = function(name) { // name 是参数 console.log("你好," + name + "!"); };
函数声明可以在定义之前调用(存在函数提升),而函数表达式必须先定义后调用。 -
箭头函数 (Arrow Function): 在 ES6 中引入,语法更简洁,并且处理
this
关键字的方式不同(对初学者来说暂时不用深究this
)。常用于简单的函数或回调函数。“`javascript const greet = (name) => { // name 是参数 console.log(“你好,” + name + “!”); };
// 更简洁的单行箭头函数(省略花括号和 return) const add = (a, b) => a + b; console.log(add(2, 3)); // 输出 5 “`
7.2 调用函数
通过函数名加上括号 ()
来调用函数。如果在定义时有参数,调用时需要在括号内提供对应的实参。
“`javascript greet(“张三”); // 调用 greet 函数,传入实参 “张三” // 输出:你好,张三!
greet(“李四”); // 再次调用 greet 函数,传入实参 “李四” // 输出:你好,李四! “`
7.3 函数参数 (Parameters and Arguments)
- 参数 (Parameters): 在函数定义时,括号内列出的变量名,它们是函数的“占位符”,用于接收外部传入的数据。
- 实参 (Arguments): 在函数调用时,括号内提供的值,它们是传递给参数的实际数据。
“`javascript function calculateArea(width, height) { // width 和 height 是参数 return width * height; // 函数可以返回值 }
let area = calculateArea(10, 5); // 10 和 5 是实参 console.log(“面积是:” + area); // 输出 面积是:50 “`
7.4 返回值 (Return Value)
函数可以使用 return
语句返回一个值。当执行到 return
语句时,函数会立即停止执行,并将指定的值返回给调用它的地方。
如果函数没有 return
语句,或者 return
语句后面没有跟任何值,函数会默认返回 undefined
。
“`javascript function multiply(x, y) { return x * y; // 返回乘积 }
let product = multiply(4, 6); // product 变量接收函数的返回值 24 console.log(product); // 输出 24
function doNothing() { console.log(“我什么也没返回”); // 没有 return 语句 } let result = doNothing(); console.log(result); // 输出 undefined “`
7.5 作用域 (Scope) (重要概念,了解即可)
作用域决定了变量和函数的可见性。
- 全局作用域 (Global Scope): 在任何函数、代码块之外声明的变量拥有全局作用域,在代码的任何地方都可以访问。
- 函数作用域 (Function Scope): 使用
var
在函数内部声明的变量拥有函数作用域,只能在函数内部访问。 - 块作用域 (Block Scope): 使用
let
或const
在代码块(如if
语句、for
循环、{}
大括号)内部声明的变量拥有块作用域,只能在该代码块内部访问。
现代 JavaScript 推荐使用 let
和 const
,它们引入的块作用域有助于避免变量命名冲突和提高代码的可预测性。
“`javascript let globalVar = “我是全局变量”;
function testScope() { let functionVar = “我是函数变量”; // 函数作用域 if (true) { let blockVar = “我是块变量”; // 块作用域 console.log(globalVar); // 可访问 console.log(functionVar); // 可访问 console.log(blockVar); // 可访问 } // console.log(blockVar); // 错误:无法在块外部访问 blockVar }
testScope(); console.log(globalVar); // 可访问 // console.log(functionVar); // 错误:无法在函数外部访问 functionVar “`
第八章:对象与数组:组织数据
当我们需要处理复杂数据时,原始数据类型就不够用了。对象和数组是 JavaScript 中用于组织和管理数据的两种重要结构。
8.1 对象 (Objects)
对象是无序的键值对集合。每个键值对称为对象的属性。键(属性名)通常是字符串,值可以是任何数据类型(包括其他对象、数组或函数)。
“`javascript // 定义一个对象 let person = { // 属性名: 属性值 name: “Alice”, age: 30, isStudent: false, address: { // 属性值也可以是另一个对象 city: “Beijing”, zip: “100000” }, hobbies: [“reading”, “hiking”], // 属性值也可以是数组 greet: function() { // 属性值也可以是函数 (称为方法) console.log(“你好,我的名字是 ” + this.name); // this 指向当前对象 } };
// 访问对象属性 console.log(person.name); // 使用点号 . 访问属性 (推荐) -> 输出 “Alice” console.log(person[“age”]); // 使用方括号 [] 访问属性 (当属性名是变量或包含特殊字符时有用) -> 输出 30 console.log(person.address.city); // 访问嵌套对象的属性 -> 输出 “Beijing”
// 修改对象属性 person.age = 31; person[“isStudent”] = true;
// 添加新属性 person.job = “Engineer”;
// 调用对象方法 person.greet(); // 输出 “你好,我的名字是 Alice”
console.log(person); // 输出整个对象 / { name: ‘Alice’, age: 31, isStudent: true, address: { city: ‘Beijing’, zip: ‘100000’ }, hobbies: [ ‘reading’, ‘hiking’ ], greet: [Function: greet], job: ‘Engineer’ } / “`
8.2 数组 (Arrays)
数组是有序的数据集合,其中的每个数据称为元素。数组的元素可以通过它们的索引(从 0 开始的数字)来访问。
“`javascript // 定义一个数组 let colors = [“red”, “green”, “blue”];
// 访问数组元素 console.log(colors[0]); // 访问第一个元素 (索引为 0) -> 输出 “red” console.log(colors[1]); // 访问第二个元素 (索引为 1) -> 输出 “green” console.log(colors[2]); // 访问第三个元素 (索引为 2) -> 输出 “blue” console.log(colors[3]); // 访问不存在的元素 -> 输出 undefined
// 数组的长度 console.log(colors.length); // 输出 3
// 修改数组元素 colors[1] = “yellow”; console.log(colors); // 输出 [“red”, “yellow”, “blue”]
// 添加元素 colors.push(“purple”); // 在末尾添加元素 console.log(colors); // 输出 [“red”, “yellow”, “blue”, “purple”]
// 删除元素 colors.pop(); // 删除末尾元素 console.log(colors); // 输出 [“red”, “yellow”, “blue”]
// 遍历数组 (常用 for 循环或 for…of 循环) for (let i = 0; i < colors.length; i++) { console.log(“颜色: ” + colors[i]); } / 输出: 颜色: red 颜色: yellow 颜色: blue /
for (let color of colors) {
console.log(“颜色 (for…of): ” + color);
}
/
输出:
颜色 (for…of): red
颜色 (for…of): yellow
颜色 (for…of): blue
/
``
数组还有许多其他内置方法,如
unshift()(在开头添加),
shift()(删除开头),
slice()(截取),
splice()(增删改),
indexOf()(查找索引),
forEach()(遍历),
map()(映射),
filter()` (过滤) 等等。随着学习深入,你会逐渐接触并使用它们。
第九章:与网页互动:深入理解 DOM
前面学习的 JavaScript 基础知识可以在任何 JavaScript 环境中运行(浏览器、Node.js 等)。但要在网页中实现动态效果,我们就需要学习如何使用 JavaScript 与网页文档 (Document) 进行交互,这涉及到 DOM (Document Object Model)。
9.1 DOM 是什么?
当你加载一个 HTML 页面时,浏览器会解析 HTML 代码,并创建一个树形结构来表示页面的内容和结构。这个树形结构就是 DOM。DOM 将 HTML 页面中的每个元素(如 <html>
, <head>
, <body>
, <h1>
, <p>
, <div>
等)视为一个节点 (Node),并允许 JavaScript 通过这个模型来访问、修改和操作这些节点。
你可以把 DOM 看作是 HTML 页面的一个编程接口。
9.2 访问 DOM 元素 (选择元素)
要操作页面上的元素,首先需要找到它们。JavaScript 提供了多种方法来选择 DOM 元素。
-
document.getElementById(id)
: 通过元素的id
属性选择一个元素。id
在页面中应该是唯一的。html <p id="myParagraph">这是一段文字。</p> <script> const myPara = document.getElementById("myParagraph"); console.log(myPara); // 输出整个 <p> 元素 </script>
-
document.getElementsByClassName(className)
: 通过元素的class
属性选择一组元素。返回一个HTMLCollection (类似于数组,但不是真正的数组)。html <div class="myClass">第一个</div> <div class="myClass">第二个</div> <script> const elements = document.getElementsByClassName("myClass"); console.log(elements[0]); // 访问第一个带有 myClass 的元素 console.log(elements.length); // 获取元素的数量 </script>
-
document.getElementsByTagName(tagName)
: 通过元素的标签名选择一组元素(如div
,p
,a
等)。返回一个 HTMLCollection。html <p>段落一</p> <p>段落二</p> <script> const paragraphs = document.getElementsByTagName("p"); console.log(paragraphs[0]); // 访问第一个 <p> 元素 </script>
-
document.querySelector(selector)
: 使用 CSS 选择器语法选择第一个匹配的元素。这是非常强大和常用的方法。html <div id="container"> <p class="text">第一段</p> <p class="text highlight">第二段</p> </div> <script> const firstPara = document.querySelector("#container .text"); // 选择 id 为 container 下第一个 class 为 text 的元素 console.log(firstPara); // 输出第一个 <p class="text">... </script>
-
document.querySelectorAll(selector)
: 使用 CSS 选择器语法选择所有匹配的元素。返回一个 NodeList (类似于数组)。html <div class="item">苹果</div> <div class="item">香蕉</div> <script> const items = document.querySelectorAll(".item"); // 选择所有 class 为 item 的元素 console.log(items.length); // 输出 2 console.log(items[1]); // 访问第二个元素 -> 输出 <div class="item">香蕉</div> </script>
建议: 在大多数情况下,优先使用querySelector
和querySelectorAll
,因为它们使用标准的 CSS 选择器语法,更灵活方便。
9.3 操作 DOM 元素 (修改内容、属性、样式)
获取到元素后,你可以修改它们的内容、属性或样式。
-
修改元素内容:
element.innerHTML
: 获取或设置元素的 HTML 内容(包括子元素)。element.textContent
: 获取或设置元素的纯文本内容(忽略 HTML 标签)。
html <div id="content">原始内容</div> <script> const contentDiv = document.getElementById("content"); contentDiv.innerHTML = "<strong>新的</strong> 内容"; // 设置 HTML 内容 // contentDiv.textContent = "新的纯文本内容"; // 设置纯文本内容 </script>
-
修改元素属性:
element.attributeName
: 直接访问或设置元素的标准 HTML 属性(如src
,href
,id
,class
,style
等)。element.setAttribute(attributeName, value)
: 设置元素的属性。element.getAttribute(attributeName)
: 获取元素的属性值。element.removeAttribute(attributeName)
: 移除元素的属性。
“`html
“` -
修改元素样式:
element.style.propertyName
: 直接访问或设置元素的内联样式。CSS 属性名通常使用驼峰命名法(如backgroundColor
,fontSize
)。
html
<div id="styledDiv">这段文字会改变颜色。</div>
<script>
const styledDiv = document.getElementById("styledDiv");
styledDiv.style.color = "red"; // 设置字体颜色为红色
styledDiv.style.backgroundColor = "yellow"; // 设置背景颜色
</script>
注意:直接修改style
会添加内联样式,优先级很高。更推荐通过修改元素的 class 来改变样式,这样更容易管理和维护。 -
修改元素的 class:
element.classList
: 一个非常有用的属性,提供了添加、移除、切换 class 的方法。
“`html
操作我的 Class
“`
9.4 事件处理 (Event Handling)
事件是在网页中发生的动作或发生的事情,例如:
* 用户点击按钮
* 鼠标移动到某个元素上
* 键盘按下
* 页面加载完成
* 表单提交
JavaScript 可以监听这些事件,并在事件发生时执行特定的代码(称为事件处理程序或回调函数)。
处理事件的常用方法是使用 addEventListener()
。
“`html
``
addEventListener()方法接收两个主要参数:
“click”
1. 要监听的事件类型(如,
“mouseover”,
“keydown”,
“submit”,
“load”` 等,事件类型需要是小写字符串)。
2. 当事件发生时要执行的函数。
这是前端交互的核心机制之一。
第十章:调试:找到问题所在
在编写代码的过程中,出现错误是不可避免的。学会如何找到并修复错误(调试)是一项非常重要的技能。
10.1 使用 console.log()
输出信息
这是最简单直接的调试方法。在代码的任何位置,你可以使用 console.log()
输出变量的值、程序的执行流程信息等,然后在浏览器控制台中查看输出。
javascript
let sum = 0;
for (let i = 1; i <= 5; i++) {
sum += i;
console.log("当前 i 的值:", i, "当前 sum 的值:", sum); // 输出中间过程的值
}
console.log("循环结束,最终 sum 的值:", sum);
除了 console.log()
, console
对象还提供了其他有用的方法:
* console.warn()
: 输出警告信息。
* console.error()
: 输出错误信息。
* console.info()
: 输出信息性消息。
* console.table()
: 以表格形式输出数组或对象数据。
* console.time()
/ console.timeEnd()
: 测量代码执行时间。
10.2 使用浏览器开发者工具的调试器 (Debugger)
现代浏览器都内置了强大的调试器,允许你:
* 设置断点 (Breakpoints): 代码会在断点处暂停执行。
* 单步执行 (Step through): 一行一行地执行代码,观察每一步的变化。
* 检查变量 (Inspect variables): 在代码暂停时,查看当前作用域中所有变量的值。
* 查看调用堆栈 (Call Stack): 查看代码是通过哪些函数调用路径执行到当前位置的。
如何使用 (以 Chrome 为例):
1. 打开开发者工具 (F12)。
2. 切换到 “Sources” (源代码) 标签页。
3. 在左侧找到你的 JavaScript 文件。
4. 点击代码行号,设置一个蓝色的断点标记。
5. 刷新页面或触发执行该段代码的操作。
6. 代码会在断点处暂停,你可以使用控制面板上的按钮进行单步执行、继续执行等操作,并在右侧的 “Scope” 和 “Watch” 面板查看变量值。
熟练使用调试器能够极大地提高你解决问题的效率。
总结与下一步
恭喜你!你已经完成了 JavaScript 入门的核心内容学习。我们一起了解了:
- JavaScript 的基本概念和用途。
- 如何在浏览器中运行 JavaScript 代码。
- JavaScript 的基本语法、变量、数据类型和运算符。
- 如何使用条件语句和循环控制程序流程。
- 如何定义和调用函数以复用代码。
- 如何使用对象和数组组织复杂数据。
- 如何使用 DOM 与网页元素进行交互,包括选择、修改和处理事件。
- 基本的调试技巧。
这只是一个开始。JavaScript 的世界非常广阔,还有很多高级概念和实用技术等待你去探索:
- 更深入的函数概念: 闭包、高阶函数、
this
关键字、原型链。 - 异步编程: 回调函数、Promise、async/await(处理耗时操作,避免页面卡死)。
- 模块化: 如何组织大型项目的代码。
- ES6+ 新特性: 解构赋值、展开运算符、类 (Classes) 等等。
- HTTP 请求 (Ajax/Fetch API): 如何从服务器获取数据,实现前后端交互。
- 存储: Local Storage 和 Session Storage。
- 错误处理:
try...catch
语句。 - 前端框架/库: React, Vue, Angular 等,它们能帮助你更高效地构建复杂的单页应用。
- Node.js: 学习如何在服务器端使用 JavaScript。
学习建议:
- 实践是关键: 光看不练是学不会编程的。尝试跟着教程中的例子敲代码,然后自己修改例子,看看会发生什么。
- 做小项目: 尝试用你学到的知识做一些有趣的小网页功能,比如一个简单的计算器、待办事项列表、图片轮播等。
- 阅读文档: 官方文档 (MDN Web Docs 是非常好的资源) 是最权威的学习资料。
- 多提问,多交流: 加入开发者社区,与其他学习者交流,向经验丰富的开发者请教。
- 坚持下去: 学习编程需要时间和耐心,遇到困难是正常的,不要轻易放弃。
希望这篇详细的入门教程为你打开了通往 JavaScript 世界的大门。祝你在编程学习的道路上旅途愉快,不断进步!