JavaScript 基础教程 – wiki基地


JavaScript 基础教程:从零开始迈出第一步

欢迎来到 JavaScript 的世界!JavaScript(简称 JS)是目前世界上最流行的编程语言之一,它主要用于网页开发,为网页增添交互性和动态效果。但它的应用远不止于此,还可以用于构建服务器端应用(Node.js)、移动应用(React Native, Ionic 等)、桌面应用(Electron)等。

本教程将带你从零开始,系统地学习 JavaScript 的核心基础知识。无论你将来想成为前端开发者、后端开发者,还是全栈工程师,扎实的 JavaScript 基础都将是你宝贵的财富。

1. 什么是 JavaScript?

JavaScript 是一种轻量级的、解释型的或即时编译型的编程语言,它遵循 ECMAScript 标准。最初被设计用于增强 HTML 页面,使其具有交互能力。简单来说,HTML 负责页面的结构,CSS 负责页面的样式,而 JavaScript 则负责页面的行为。

  • 解释型/即时编译型: 代码运行时才被翻译执行,而不是事先完全编译成机器码。现代 JS 引擎(如 V8)会使用即时编译技术优化性能。
  • 单线程: 在浏览器环境中,JavaScript 通常是单线程的,意味着同一时间只能做一件事情。但它通过事件循环等机制处理异步操作。
  • 动态弱类型: 你不需要提前声明变量的类型,类型是在运行时根据赋给变量的值自动确定的,而且变量可以被赋予不同类型的值。

2. 如何在 HTML 中引入 JavaScript?

有几种方法可以在 HTML 页面中使用 JavaScript 代码:

2.1 行内脚本 (Inline Script)

直接将 JavaScript 代码写在 HTML 标签的属性中,通常用于简单的事件处理。

html
<button onclick="alert('Hello, World!')">点击我</button>

优点: 简单方便,适用于小型交互。
缺点: 代码和结构混杂,不利于维护,不推荐大量使用。

2.2 内部脚本 (Internal Script)

使用 <script> 标签将 JavaScript 代码块直接嵌入到 HTML 文件中。通常放在 <head><body> 标签内。

“`html




内部脚本示例


内部脚本示例


“`

<script> 放在 <body> 标签的底部(</body> 之前)是常见的最佳实践,这样可以确保 HTML 结构加载完成后再执行 JavaScript 代码,避免脚本找不到需要操作的 HTML 元素。

优点: 代码和 HTML 在同一个文件,修改方便。
缺点: 如果 JS 代码量大,会使 HTML 文件变得臃肿,不利于代码复用。

2.3 外部脚本 (External Script)

将 JavaScript 代码写入一个单独的文件(通常以 .js 结尾),然后在 HTML 文件中使用 <script> 标签通过 src 属性引用这个外部文件。

“`html





外部脚本示例

外部脚本示例



“`

javascript
// script.js
console.log("这是外部脚本");
alert("外部脚本已加载!");

优点: 代码和 HTML 分离,结构清晰,易于维护和复用;浏览器可以缓存外部 JS 文件,提高加载速度。
缺点: 需要额外的文件。

最佳实践: 对于大型项目或复杂的脚本,强烈推荐使用外部脚本。

<script> 标签的属性:

  • src: 指定外部脚本文件的路径。
  • async: (HTML5 新增)脚本会异步加载,加载完成后立即执行,不会阻塞 HTML 解析。
  • defer: (HTML5 新增)脚本会异步加载,但会等到 HTML 解析完成后,在 DOMContentLoaded 事件之前执行。与 async 相比,defer 脚本会按照它们在 HTML 中出现的顺序执行。

对于普通脚本,推荐使用 defer 属性,既不阻塞 HTML 解析,又能保证脚本按顺序执行。

3. 第一个 JavaScript 程序:输出信息

学习任何编程语言,通常从输出信息开始。JavaScript 有几种常用的输出方法:

3.1 console.log()

这是最常用的输出方法,用于在浏览器的开发者工具控制台(Console)中打印信息,便于调试。

javascript
console.log("Hello, Console!");
console.log(123);
console.log(true);
console.log({ name: "Alice", age: 30 }); // 打印对象
console.log([1, 2, 3]); // 打印数组

打开网页后,按 F12 打开开发者工具,切换到 Console(控制台)标签页,就可以看到输出的信息。

3.2 alert()

在浏览器中弹出一个警告框,显示指定的信息。

javascript
alert("这是一个警告框!");

alert() 会阻塞页面后续的执行,直到用户点击“确定”按钮。不建议在正式网页中频繁使用,会打断用户体验。

3.3 prompt()

在浏览器中弹出一个输入框,提示用户输入信息,并返回用户输入的值(字符串)。如果用户点击“取消”,则返回 null

javascript
let userName = prompt("请输入你的名字:");
if (userName !== null) {
alert("你好," + userName + "!");
} else {
alert("你没有输入名字。");
}

3.4 confirm()

在浏览器中弹出一个确认框,显示一个问题,并带有“确定”和“取消”按钮。用户点击“确定”返回 true,点击“取消”返回 false

javascript
let result = confirm("你确定要删除吗?");
if (result) {
alert("已确认删除。");
} else {
alert("已取消删除。");
}

3.5 document.write()

直接将内容写入 HTML 文档中。如果在页面加载完成后执行 document.write(),会覆盖整个页面内容。

javascript
document.write("<h1>这是通过 JS 写入的标题</h1>");
document.write("<p>这是通过 JS 写入的段落</p>");

注意: document.write() 不建议在现代 Web 开发中使用,因为它会破坏已加载的文档结构,并且在异步加载脚本时可能出现问题。了解即可,调试或特殊情况外应避免使用。

4. 变量 (Variables)

变量是用于存储数据值的容器。在 JavaScript 中,声明变量有三种主要方式:varletconst

4.1 使用 var (较旧)

var 是 ES6(ECMAScript 2015)之前声明变量的唯一方式。

“`javascript
var age = 25;
var name = “Alice”;
var isStudent = true;

console.log(age); // 输出 25
console.log(name); // 输出 Alice
console.log(isStudent); // 输出 true
“`

var 的特点:
* 函数作用域: var 声明的变量只在函数内部或全局范围内有效,没有块级作用域({} 内的范围)。
* 变量提升 (Hoisting): 使用 var 声明的变量会被“提升”到其作用域的顶部。这意味着你可以在声明之前使用变量,但它的值是 undefined

javascript
console.log(carName); // 输出 undefined
var carName = "Volvo";
console.log(carName); // 输出 Volvo

4.2 使用 let (推荐)

let 是 ES6 新增的变量声明方式,推荐在现代 JavaScript 开发中使用。

“`javascript
let count = 10;
let message = “Hello”;
let isActive = false;

console.log(count);
console.log(message);
console.log(isActive);

// let 允许重新赋值
count = 11;
message = “Hi”;
console.log(count);
console.log(message);
“`

let 的特点:
* 块级作用域: let 声明的变量只在其所在的块({} 内)内有效。
* 无变量提升(或称临时死区): 你不能在声明 let 变量之前使用它,否则会报错。

javascript
// console.log(price); // ReferenceError: Cannot access 'price' before initialization
let price = 20;
console.log(price); // 输出 20

4.3 使用 const (推荐)

const 也是 ES6 新增的声明方式,用于声明常量。

“`javascript
const PI = 3.14159;
const siteName = “My Website”;
const isApproved = true;

console.log(PI);
console.log(siteName);
console.log(isApproved);

// const 不允许重新赋值
// PI = 3.14; // TypeError: Assignment to constant variable.
// siteName = “New Website”; // TypeError
“`

const 的特点:
* 块级作用域:let
* 无变量提升。
* 必须在声明时初始化: const 变量声明时必须赋值。
* 值不能重新赋值: 对于基本数据类型(如数字、字符串),const 保证变量指向的值不变。对于复杂数据类型(如对象、数组),const 保证变量指向的内存地址不变,但对象或数组内部的属性/元素是可以修改的。

“`javascript
const person = { name: “Bob”, age: 25 };
console.log(person); // { name: ‘Bob’, age: 25 }
person.age = 26; // OK, 修改对象内部属性
console.log(person); // { name: ‘Bob’, age: 26 }
// person = { name: “Charlie” }; // TypeError: Assignment to constant variable. (尝试重新指向新的对象会报错)

const numbers = [1, 2, 3];
console.log(numbers); // [ 1, 2, 3 ]
numbers.push(4); // OK, 修改数组内容
console.log(numbers); // [ 1, 2, 3, 4 ]
// numbers = [5, 6]; // TypeError: Assignment to constant variable. (尝试重新指向新的数组会报错)
“`

总结: 在现代 JavaScript 开发中,优先使用 const 声明常量(值不会改变的变量),如果变量需要重新赋值,则使用 let。尽量避免使用 var

4.4 变量命名规则

  • 变量名必须以字母、下划线(_)或美元符号($)开头。
  • 后续字符可以是字母、数字、下划线或美元符号。
  • 变量名区分大小写(myVariablemyvariable 是不同的变量)。
  • 不能使用 JavaScript 的保留关键字(如 if, for, function, var, let, const 等)。
  • 推荐使用驼峰命名法(camelCase),如 firstNamegetUserName

5. 数据类型 (Data Types)

JavaScript 是一种动态弱类型语言,变量的数据类型是在运行时确定的。JavaScript 的数据类型分为两大类:原始类型 (Primitive types) 和 对象类型 (Object type)。

5.1 原始类型 (Primitives)

原始类型的值是不可变的(它们的值本身不能被修改)。

  • String (字符串): 用于表示文本数据。使用单引号 ('')、双引号 ("") 或反引号 () 包围。

    javascript
    let greeting = "Hello, World!";
    let message = 'This is a string.';
    let template = `My name is ${name}.`; // 模板字符串,支持嵌入变量

  • Number (数字): 用于表示数值,包括整数和浮点数。

    javascript
    let age = 25; // 整数
    let price = 19.99; // 浮点数
    let largeNumber = 1e6; // 科学计数法 (1 * 10^6)
    let hexNumber = 0xff; // 十六进制
    let octalNumber = 0o377; // 八进制 (ES6)
    let binaryNumber = 0b11111111; // 二进制 (ES6)
    let notANumber = NaN; // Not a Number,表示非法的数学运算结果
    let infinity = Infinity; // 无穷大

  • Boolean (布尔值): 用于表示逻辑值,只有两个可能的值:true (真) 和 false (假)。

    javascript
    let isAdult = true;
    let hasPermission = false;

  • Null (空): 表示一个特意赋值的空值。表示此处不应该有值。

    javascript
    let car = null; // 变量car被明确设置为空

    注意: typeof null 的结果是 object。这是一个历史遗留的 bug,但已经被保留下来。

  • Undefined (未定义): 表示变量已声明但未赋值,或对象属性不存在。

    “`javascript
    let city; // 变量已声明但未赋值,默认值为 undefined
    console.log(city); // 输出 undefined
    console.log(typeof city); // 输出 undefined

    let obj = { name: “Test” };
    console.log(obj.age); // 输出 undefined,因为age属性不存在
    “`

  • Symbol (符号): (ES6 新增) 表示独一无二的值,主要用于对象属性名,避免属性名冲突。

    javascript
    const id = Symbol('id');
    const anotherId = Symbol('id');
    console.log(id === anotherId); // 输出 false

  • BigInt (大整数): (ES2020 新增) 用于表示任意精度的整数,可以表示比 Number 类型支持的范围更大的整数。以 n 结尾表示 BigInt。

    javascript
    const bigNumber = 123456789012345678901234567890n;
    console.log(bigNumber);
    console.log(typeof bigNumber); // 输出 bigint

5.2 对象类型 (Object)

对象类型表示一个复杂的数据结构,可以存储多个值作为属性。

  • Object (对象): 键值对的集合。

    javascript
    let person = {
    name: "Bob",
    age: 30,
    isStudent: false
    };
    console.log(person.name); // 访问属性:点表示法
    console.log(person['age']); // 访问属性:方括号表示法

  • Array (数组): 有序的元素集合,索引从 0 开始。

    javascript
    let colors = ["red", "green", "blue"];
    console.log(colors[0]); // 访问第一个元素
    console.log(colors.length); // 数组长度

  • Function (函数): 可执行的代码块。在 JavaScript 中,函数也是一种特殊的对象。

    javascript
    function greet(name) {
    return "Hello, " + name + "!";
    }
    console.log(greet("Alice")); // 调用函数

  • 以及其他内置对象,如 Date, RegExp, Error 等。

6. 运算符 (Operators)

运算符用于对值(操作数)执行某些操作。

6.1 算术运算符 (Arithmetic Operators)

运算符 描述 示例 结果
+ 加法 5 + 2 7
- 减法 5 - 2 3
* 乘法 5 * 2 10
/ 除法 10 / 2 5
% 取模(余数) 10 % 3 1
** 幂运算 (ES6) 2 ** 3 8
++ 自增 let i=0; i++; i 变为 1
-- 自减 let i=1; i--; i 变为 0

6.2 赋值运算符 (Assignment Operators)

运算符 示例 等同于
= x = y x = y
+= x += y x = x + y
-= x -= y x = x - y
*= x *= y x = x * y
/= x /= y x = x / y
%= x %= y x = x % y
**= x **= y x = x ** y

6.3 比较运算符 (Comparison Operators)

用于比较两个值,返回布尔值 (truefalse)。

运算符 描述 示例 结果
== 相等 (值相等) 5 == "5" true
!= 不相等 (值不等) 5 != "5" false
=== 严格相等 (值和类型都相等) 5 === "5" false
!== 严格不相等 (值或类型不等) 5 !== "5" true
> 大于 5 > 2 true
< 小于 5 < 2 false
>= 大于等于 5 >= 5 true
<= 小于等于 5 <= 2 false

重要: 在实际开发中,强烈推荐使用严格相等 (===) 和严格不相等 (!==),以避免类型转换带来的意外结果。

6.4 逻辑运算符 (Logical Operators)

用于组合布尔值或表达式。

运算符 描述 示例 结果
&& 逻辑与 true && false false (两边都为真才为真)
|| 逻辑或 true || false true (一边为真即为真)
! 逻辑非 !true false (取反)

短路评估: &&|| 运算符具有短路特性。对于 &&,如果左边表达式为假,则右边不再执行;对于 ||,如果左边表达式为真,则右边不再执行。

6.5 类型运算符 (Type Operators)

运算符 描述 示例 结果
typeof 返回变量的类型 typeof "hello" "string"
instanceof 检查对象是否是某个类的实例 [1, 2] instanceof Array true

7. 控制流 (Control Flow)

控制流语句用于根据条件决定代码的执行路径,或重复执行某些代码块。

7.1 条件语句 (Conditional Statements)

if, else if, else

“`javascript
let score = 85;

if (score >= 90) {
console.log(“优秀”);
} else if (score >= 80) {
console.log(“良好”);
} else if (score >= 60) {
console.log(“及格”);
} else {
console.log(“不及格”);
}
“`

switch

用于基于不同的条件执行不同的代码块。

“`javascript
let day = 3;
let dayName;

switch (day) {
case 1:
dayName = “星期一”;
break;
case 2:
dayName = “星期二”;
break;
case 3:
dayName = “星期三”;
break;
// … 其他 case
default: // 如果所有 case 都不匹配,执行 default
dayName = “未知日期”;
}
console.log(dayName); // 输出 星期三
“`

注意 break 语句: break 用于跳出 switch 结构。如果没有 break,代码会继续执行下一个 case 中的语句,直到遇到 breakswitch 结束。

7.2 循环语句 (Loop Statements)

用于重复执行一段代码。

for 循环

通常用于已知循环次数的情况。

“`javascript
// 从 0 数到 4 (不包含 5)
for (let i = 0; i < 5; i++) {
console.log(“循环次数:” + i);
}

// 遍历数组
const fruits = [“apple”, “banana”, “cherry”];
for (let i = 0; i < fruits.length; i++) {
console.log(“水果:” + fruits[i]);
}
“`

while 循环

当条件为真时,重复执行代码块。通常用于循环次数未知的情况。

javascript
let count = 0;
while (count < 5) {
console.log("计数器:" + count);
count++; // 别忘了更新条件,否则可能造成死循环
}

do...while 循环

先执行一次代码块,然后判断条件。至少会执行一次。

javascript
let i = 0;
do {
console.log("至少执行一次:" + i);
i++;
} while (i < 5);

for...in 循环

遍历对象的属性名(键)。

javascript
const person = { name: "Alice", age: 30, city: "New York" };
for (let key in person) {
console.log(key + ": " + person[key]);
}
// 输出:
// name: Alice
// age: 30
// city: New York

for...of 循环 (ES6)

遍历可迭代对象(如数组、字符串、Map、Set 等)的值。

“`javascript
const colors = [“red”, “green”, “blue”];
for (let color of colors) {
console.log(“颜色:” + color);
}
// 输出:
// 颜色:red
// 颜色:green
// 颜色:blue

const str = “hello”;
for (let char of str) {
console.log(“字符:” + char);
}
// 输出:
// 字符:h
// 字符:e`
// 字符:l
// 字符:l
// 字符:o
“`

7.3 breakcontinue

  • break: 立即终止整个循环。
  • continue: 终止当前循环的本次迭代,跳到下一次迭代。

javascript
for (let i = 0; i < 10; i++) {
if (i === 3) {
continue; // 跳过 3
}
if (i === 7) {
break; // 当 i 等于 7 时终止循环
}
console.log(i); // 输出 0, 1, 2, 4, 5, 6
}

8. 函数 (Functions)

函数是一段可重复使用的代码块,用于执行特定任务。使用函数可以提高代码的组织性、可读性和可维护性。

8.1 函数声明 (Function Declaration)

“`javascript
// 声明一个函数
function greet(name) {
return “Hello, ” + name + “!”;
}

// 调用函数
let greeting = greet(“Alice”);
console.log(greeting); // 输出 “Hello, Alice!”

console.log(greet(“Bob”)); // 输出 “Hello, Bob!”
“`

特点:
* 使用 function 关键字。
* 函数名是必须的。
* 函数声明存在变量提升,可以在声明之前调用。

8.2 函数表达式 (Function Expression)

将一个匿名函数或命名函数赋值给一个变量。

“`javascript
// 函数表达式
const sayHello = function(name) {
return “Hello, ” + name + “!”;
};

// 调用函数 (通过变量名)
let message = sayHello(“Charlie”);
console.log(message); // 输出 “Hello, Charlie!”

// 函数表达式不存在变量提升,必须在声明后调用
// greetAgain(“David”); // ReferenceError: Cannot access ‘greetAgain’ before initialization
const greetAgain = function(name) {
console.log(“Hello again, ” + name + “!”);
};
greetAgain(“David”); // OK
“`

8.3 箭头函数 (Arrow Functions) (ES6)

一种更简洁的函数表达式语法。

“`javascript
// 箭头函数的基本语法
const add = (a, b) => {
return a + b;
};
console.log(add(2, 3)); // 输出 5

// 如果函数体只有一行 return 语句,可以省略 {} 和 return 关键字
const subtract = (a, b) => a – b;
console.log(subtract(5, 2)); // 输出 3

// 如果只有一个参数,可以省略参数的 ()
const double = number => number * 2;
console.log(double(5)); // 输出 10

// 如果没有参数,需要保留 ()
const sayHi = () => console.log(“Hi!”);
sayHi(); // 输出 “Hi!”

// 返回对象字面量时,需要用 () 包围
const createPerson = (name, age) => ({ name: name, age: age });
console.log(createPerson(“Eve”, 28)); // 输出 { name: ‘Eve’, age: 28 }
“`

箭头函数的特点:
* 语法更简洁。
* 没有自己的 thisargumentssupernew.target 绑定。this 的值继承自外围最近的非箭头函数作用域(词法作用域)。这是箭头函数与普通函数表达式的最大区别之一。

8.4 函数参数 (Function Parameters)

函数可以接受参数,参数是函数内部使用的局部变量。

“`javascript
function multiply(x, y) { // x 和 y 是参数
return x * y;
}

let result = multiply(4, 5); // 4 和 5 是实参 (arguments)
console.log(result); // 输出 20
“`

  • 默认参数 (Default Parameters) (ES6): 可以为参数设置默认值。

    javascript
    function greeting(name = "Guest") {
    console.log("Hello, " + name);
    }
    greeting(); // 输出 "Hello, Guest"
    greeting("Peter"); // 输出 "Hello, Peter"

  • 剩余参数 (Rest Parameters) (ES6): 使用 ... 语法将不定数量的参数收集到一个数组中。

    javascript
    function sumAll(...numbers) { // numbers 是一个数组
    let total = 0;
    for (let number of numbers) {
    total += number;
    }
    return total;
    }
    console.log(sumAll(1, 2, 3)); // 输出 6
    console.log(sumAll(1, 2, 3, 4, 5)); // 输出 15

8.5 返回值 (Return Value)

函数可以使用 return 语句返回值。如果没有 return 语句,或者 return 语句后面没有值,函数默认返回 undefined

“`javascript
function addNumbers(a, b) {
return a + b; // 返回 a 和 b 的和
console.log(“这行代码不会被执行”); // return 语句后的代码不可达
}

let sum = addNumbers(10, 20);
console.log(sum); // 输出 30

function doNothing() {
// 没有 return 语句
}
console.log(doNothing()); // 输出 undefined
“`

9. 数组 (Arrays)

数组是用于存储有序数据集合的特殊变量。数组的元素可以是任何数据类型。

9.1 创建数组

“`javascript
// 数组字面量 (常用)
let fruits = [“apple”, “banana”, “cherry”];

// 使用 Array 构造函数
let numbers = new Array(1, 2, 3, 4, 5);
let emptyArray = new Array(); // 创建一个空数组
let fixedSizeArray = new Array(10); // 创建一个长度为10,元素都是 undefined 的数组
“`

9.2 访问数组元素

数组元素通过索引访问,索引从 0 开始。

javascript
let colors = ["red", "green", "blue"];
console.log(colors[0]); // 输出 "red"
console.log(colors[1]); // 输出 "green"
console.log(colors[2]); // 输出 "blue"
console.log(colors[3]); // 输出 undefined (索引越界)

9.3 修改数组元素

javascript
let scores = [90, 85, 70];
scores[1] = 88; // 修改第二个元素
console.log(scores); // 输出 [90, 88, 70]

9.4 数组长度

length 属性返回数组的元素个数。

javascript
let items = ["pen", "book", "pencil"];
console.log(items.length); // 输出 3

通过修改 length 属性可以改变数组的长度:增大时会添加 undefined 元素,减小时会截断数组。

“`javascript
let arr = [1, 2, 3, 4, 5];
arr.length = 3;
console.log(arr); // 输出 [1, 2, 3]

arr.length = 5;
console.log(arr); // 输出 [1, 2, 3, undefined, undefined]
“`

9.5 常用的数组方法

数组对象提供了许多内置方法,用于对数组进行操作。

  • push(): 在数组末尾添加一个或多个元素,并返回新长度。

    javascript
    let fruits = ["apple", "banana"];
    fruits.push("orange");
    console.log(fruits); // ["apple", "banana", "orange"]

  • pop(): 删除数组末尾的元素,并返回被删除的元素。

    javascript
    let fruits = ["apple", "banana", "orange"];
    let lastFruit = fruits.pop();
    console.log(fruits); // ["apple", "banana"]
    console.log(lastFruit); // "orange"

  • unshift(): 在数组开头添加一个或多个元素,并返回新长度。

    javascript
    let fruits = ["banana", "cherry"];
    fruits.unshift("apple");
    console.log(fruits); // ["apple", "banana", "cherry"]

  • shift(): 删除数组开头的元素,并返回被删除的元素。

    javascript
    let fruits = ["apple", "banana", "cherry"];
    let firstFruit = fruits.shift();
    console.log(fruits); // ["banana", "cherry"]
    console.log(firstFruit); // "apple"

  • indexOf(): 返回某个元素在数组中第一次出现的索引,如果不存在则返回 -1。

    javascript
    let colors = ["red", "green", "blue", "green"];
    console.log(colors.indexOf("green")); // 输出 1
    console.log(colors.indexOf("yellow")); // 输出 -1

  • forEach(): 遍历数组,对每个元素执行一次回调函数。

    javascript
    let numbers = [1, 2, 3];
    numbers.forEach(function(number, index, array) {
    console.log(`元素:${number},索引:${index}`);
    });
    // 或使用箭头函数:
    numbers.forEach(number => console.log(number * 2));

还有许多其他有用的数组方法,如 map(), filter(), reduce(), slice(), splice(), concat(), join() 等,这些在进阶学习中会详细介绍。

10. 对象 (Objects)

对象是 JavaScript 中最重要的概念之一。对象是属性(properties)的集合,每个属性都有一个名称(键,key)和一个值(value)。

10.1 创建对象

对象字面量 (常用)

javascript
let person = {
firstName: "John",
lastName: "Doe",
age: 30,
isStudent: false,
// 方法 (函数作为属性的值)
greet: function() {
return "Hello, my name is " + this.firstName; // this 指向当前对象
},
// ES6 简写方法语法
sayAge() {
console.log("I am " + this.age + " years old.");
}
};

使用 new Object()

javascript
let car = new Object();
car.brand = "Toyota";
car.model = "Camry";
car.year = 2020;

10.2 访问对象属性

使用点表示法 (.) 或方括号表示法 ([])。

“`javascript
let person = { firstName: “John”, lastName: “Doe” };

console.log(person.firstName); // 输出 “John”
console.log(person[‘lastName’]); // 输出 “Doe”

// 方括号表示法适用于属性名是变量或包含特殊字符的情况
let propName = ‘age’;
// console.log(person.propName); // 错误,会查找名为 ‘propName’ 的属性
console.log(person[propName]); // OK, 会查找名为 ‘age’ 的属性 (如果存在)

// 访问不存在的属性会得到 undefined
console.log(person.city); // 输出 undefined
“`

10.3 修改和添加属性

“`javascript
let user = { name: “Alice”, age: 25 };

// 修改属性
user.age = 26;
user[‘name’] = “Alice Smith”;

// 添加属性
user.city = “London”;
user[‘job’] = “Engineer”;

console.log(user); // 输出 { name: ‘Alice Smith’, age: 26, city: ‘London’, job: ‘Engineer’ }
“`

10.4 删除属性

使用 delete 运算符。

“`javascript
let book = { title: “1984”, author: “George Orwell”, year: 1949 };
console.log(book); // { title: ‘1984’, author: ‘George Orwell’, year: 1949 }

delete book.year; // 或 delete book[‘year’];
console.log(book); // { title: ‘1984’, author: ‘George Orwell’ }
“`

10.5 访问对象方法

属性的值如果是函数,就称为对象的方法。

“`javascript
let person = {
firstName: “John”,
lastName: “Doe”,
fullName: function() {
return this.firstName + ” ” + this.lastName;
}
};

console.log(person.fullName()); // 调用方法,输出 “John Doe”
// 注意:不要在方法名后面加括号来访问方法本身,而不是调用它:
// console.log(person.fullName); // 输出 function() { return this.firstName + ” ” + this.lastName; }
“`

10.6 this 关键字

在对象方法中,this 关键字指向调用该方法的对象。在全局作用域中,this 通常指向全局对象(在浏览器中是 window)。箭头函数中的 this 行为有所不同,它没有自己的 this,而是继承自外围作用域。理解 this 的指向是 JavaScript 的一个重要部分。

11. JavaScript 与 HTML 的交互 (DOM 简介)

JavaScript 最常见的用途是操作 HTML 页面,这通过 Document Object Model (DOM) 实现。DOM 将 HTML 文档表示为一个树形结构,JavaScript 可以通过 DOM API 访问、修改和删除页面上的元素。

11.1 获取 HTML 元素

  • 通过 ID 获取元素:document.getElementById('id')

    javascript
    // 假设 HTML 中有一个 <p id="myParagraph"></p>
    const paragraph = document.getElementById('myParagraph');
    console.log(paragraph); // 输出对应的 <p> 元素对象

  • 通过类名获取元素:document.getElementsByClassName('className') (返回一个 HTMLCollection)

    javascript
    // 假设 HTML 中有多个 <div class="myClass"></div>
    const elements = document.getElementsByClassName('myClass');
    console.log(elements[0]); // 访问第一个匹配的元素

  • 通过标签名获取元素:document.getElementsByTagName('tagName') (返回一个 HTMLCollection)

    javascript
    // 获取页面中所有的 <p> 元素
    const paragraphs = document.getElementsByTagName('p');

  • 通过 CSS 选择器获取元素:document.querySelector('selector') (返回第一个匹配的元素)

    javascript
    const firstParagraph = document.querySelector('p'); // 第一个 <p>
    const myDiv = document.querySelector('#myId'); // ID 为 myId 的元素
    const firstElementWithClass = document.querySelector('.myClass'); // 第一个 class 为 myClass 的元素

  • 通过 CSS 选择器获取所有匹配的元素:document.querySelectorAll('selector') (返回一个 NodeList)

    javascript
    const allParagraphs = document.querySelectorAll('p'); // 所有 <p> 元素
    const allElementsWithClass = document.querySelectorAll('.myClass'); // 所有 class 为 myClass 的元素

11.2 修改 HTML 元素内容

  • innerHTML: 设置或获取元素的 HTML 内容 (会解析 HTML 标签)。

    javascript
    const myDiv = document.getElementById('myDiv');
    myDiv.innerHTML = '<h2>新的标题</h2><p>新的段落。</p>';

  • textContent: 设置或获取元素的文本内容 (不会解析 HTML 标签,当作纯文本处理)。

    javascript
    const myParagraph = document.getElementById('myParagraph');
    myParagraph.textContent = '新的纯文本内容';

11.3 修改 HTML 元素属性

“`javascript
const myImage = document.getElementById(‘myImage’); // 假设是

myImage.src = ‘new.jpg’; // 修改 src 属性
myImage.alt = ‘新的图片描述’; // 修改 alt 属性

// 设置自定义属性或标准属性
myImage.setAttribute(‘data-info’, ‘some data’);
myImage.setAttribute(‘id’, ‘newImageId’); // 也可以修改 id
“`

11.4 修改 CSS 样式

使用元素的 style 属性。

“`javascript
const myElement = document.getElementById(‘myElement’);

myElement.style.color = ‘blue’; // 修改字体颜色
myElement.style.fontSize = ’20px’; // 修改字体大小 (注意使用驼峰命名法)
myElement.style.backgroundColor = ‘lightgray’; // 修改背景颜色
“`

11.5 事件处理 (Events)

JavaScript 可以响应用户的操作或页面的状态变化,这些操作和变化被称为事件(Events),例如点击按钮、鼠标移动、页面加载完成等。

为元素添加事件监听器:

“`javascript
// 假设有一个按钮
const myButton = document.getElementById(‘myButton’);

// 方法 1: 使用 onxxx 属性 (不推荐多个监听器)
// myButton.onclick = function() {
// alert(‘按钮被点击了!’);
// };

// 方法 2: 使用 addEventListener() (推荐,可以添加多个监听器)
myButton.addEventListener(‘click’, function() {
alert(‘按钮被点击了!’);
});

myButton.addEventListener(‘mouseover’, function() {
console.log(‘鼠标移到按钮上’);
});
“`

常见的事件类型:
* click: 鼠标点击
* mouseover: 鼠标移到元素上
* mouseout: 鼠标从元素移开
* mousedown: 鼠标按下
* mouseup: 鼠标松开
* keydown: 键盘按下
* keyup: 键盘松开
* submit: 表单提交
* load: 页面或图片加载完成
* DOMContentLoaded: HTML DOM 树加载并解析完成 (不等待图片、样式表等)

12. 注释 (Comments)

注释用于解释代码,提高代码可读性,不会被浏览器执行。

  • 单行注释: 使用 //

    javascript
    // 这是一行单行注释
    let x = 10; // 声明一个变量 x

  • 多行注释: 使用 /* */

    javascript
    /*
    这是
    一个
    多行注释
    */
    let y = 20;

13. 总结与展望

恭喜你!你已经学习了 JavaScript 最核心的基础知识:

  • 如何在 HTML 中引入 JS
  • 输出信息的方法
  • 变量的声明 (var, let, const) 和命名
  • 基本数据类型 (string, number, boolean, null, undefined, symbol, bigint) 和对象类型
  • 运算符
  • 控制流 (if, switch, for, while, do...while, break, continue)
  • 函数的定义、调用、参数和返回值
  • 数组的使用和常用方法
  • 对象的使用和属性/方法的访问
  • 通过 DOM API 与 HTML 页面交互
  • 事件处理

这些知识是构建任何 JavaScript 应用的基石。但这仅仅是开始!JavaScript 还有很多更深入和高级的概念需要学习,例如:

  • 作用域和闭包 (Scope and Closures)
  • 原型和原型链 (Prototypes and Prototype Chain)
  • 面向对象编程 (Object-Oriented Programming)
  • 异步编程 (Callbacks, Promises, async/await)
  • 模块化 (Modules)
  • 错误处理 (Error Handling)
  • 严格模式 (Strict Mode)
  • 更高级的数组和对象方法
  • 浏览器 BOM (Browser Object Model)
  • ES6+ 新特性

建议你在学习完这些基础知识后,通过多写代码练习来巩固,尝试实现一些简单的网页交互效果。然后,可以继续深入学习上述进阶主题,或者开始学习某个 JavaScript 框架/库(如 React, Vue, Angular)来构建更复杂的应用。

编程是一个持续学习和实践的过程,祝你在 JavaScript 的学习旅程中取得成功!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部