JavaScript 从入门到精通:完整语法指南

JavaScript 语法完全指南:从入门到精通

本文是一篇面向初学者的 JavaScript 语法教程,从最基础的概念到高级特性,每个知识点都配有详细的示例代码和解释,让小白也能轻松掌握 JavaScript。


📚 目录


一、JavaScript 简介

1.1 什么是 JavaScript?

JavaScript (简称 JS)是一种解释型的编程语言,主要用于:

  • 网页交互:让网页"动起来"(点击按钮、表单验证等)
  • 后端开发:Node.js 让 JavaScript 可以在服务器运行
  • 移动开发:React Native、Ionic 等框架
  • 桌面应用:Electron 框架

1.2 JavaScript 的特点

  • 解释型语言:不需要编译,浏览器直接执行
  • 弱类型语言:变量类型可以自动转换
  • 动态语言:可以在运行时修改对象和函数
  • 跨平台:可以在浏览器、服务器、移动设备运行

1.3 第一个 JavaScript 程序

javascript 复制代码
// 在浏览器控制台(F12)中运行
console.log("Hello, World!");

// 输出:Hello, World!

说明

  • console.log():在控制台输出内容
  • //:单行注释
  • /* */:多行注释

二、变量与数据类型

2.1 变量声明

var(旧方式,不推荐)
javascript 复制代码
var name = "张三";
var age = 20;
var isStudent = true;

// 可以重复声明(不推荐)
var name = "李四";  // 不会报错,但会覆盖之前的值
let(推荐,块级作用域)
javascript 复制代码
let name = "张三";
let age = 20;

// 不能重复声明
let name = "李四";  // ❌ 报错:Identifier 'name' has already been declared

// 可以重新赋值
name = "李四";  // ✅ 正确
const(常量,推荐)
javascript 复制代码
const PI = 3.14159;
const MAX_SIZE = 100;

// 不能重新赋值
PI = 3.14;  // ❌ 报错:Assignment to constant variable

// 必须初始化
const name;  // ❌ 报错:Missing initializer in const declaration

选择建议

  • 优先使用 const:如果值不会改变
  • 使用 let:如果值需要改变
  • 避免使用 var:有作用域问题

2.2 数据类型

JavaScript 有 8 种数据类型

1. 基本类型(Primitive Types)
Number(数字)
javascript 复制代码
let age = 20;           // 整数
let price = 99.99;      // 小数
let temperature = -10;   // 负数
let infinity = Infinity; // 无穷大
let notANumber = NaN;   // 不是数字

// 科学计数法
let bigNumber = 1e6;    // 1000000
let smallNumber = 1e-3; // 0.001

// 类型检查
console.log(typeof age);  // "number"
String(字符串)
javascript 复制代码
let name1 = "张三";      // 双引号
let name2 = '李四';      // 单引号
let name3 = `王五`;      // 模板字符串(ES6)

// 字符串拼接
let fullName = name1 + " " + name2;  // "张三 李四"

// 模板字符串(推荐)
let message = `你好,我是${name1}`;  // "你好,我是张三"

// 字符串方法
let text = "Hello World";
console.log(text.length);        // 11(长度)
console.log(text.toUpperCase()); // "HELLO WORLD"
console.log(text.toLowerCase()); // "hello world"
console.log(text.substring(0, 5)); // "Hello"
Boolean(布尔值)
javascript 复制代码
let isStudent = true;
let isWorking = false;

// 布尔值转换
console.log(Boolean(1));      // true
console.log(Boolean(0));      // false
console.log(Boolean(""));     // false(空字符串)
console.log(Boolean("hello")); // true(非空字符串)
console.log(Boolean(null));    // false
console.log(Boolean(undefined)); // false
Undefined(未定义)
javascript 复制代码
let name;
console.log(name);        // undefined
console.log(typeof name); // "undefined"

// 未赋值的变量默认是 undefined
Null(空值)
javascript 复制代码
let user = null;
console.log(user);        // null
console.log(typeof user); // "object"(这是 JavaScript 的 bug)

// null 表示"空值",undefined 表示"未定义"
Symbol(符号,ES6)
javascript 复制代码
// 创建唯一的标识符
let id1 = Symbol("id");
let id2 = Symbol("id");
console.log(id1 === id2); // false(每个 Symbol 都是唯一的)

// 常用于对象属性名
let user = {
    [id1]: "12345"
};
BigInt(大整数,ES2020)
javascript 复制代码
// 处理超出 Number 范围的整数
let bigNumber = 9007199254740991n;  // 注意末尾的 n
let anotherBig = BigInt("9007199254740991");

console.log(bigNumber + 1n); // 9007199254740992n
2. 引用类型(Reference Types)
Object(对象)
javascript 复制代码
// 对象字面量
let user = {
    name: "张三",
    age: 20,
    isStudent: true,
    sayHello: function() {
        console.log("你好!");
    }
};

// 访问属性
console.log(user.name);        // "张三"
console.log(user["age"]);      // 20(方括号方式)
user.sayHello();                // "你好!"

// 添加属性
user.email = "zhangsan@example.com";

// 删除属性
delete user.isStudent;
Array(数组)
javascript 复制代码
// 数组字面量
let fruits = ["苹果", "香蕉", "橙子"];

// 访问元素
console.log(fruits[0]);  // "苹果"(索引从 0 开始)
console.log(fruits.length); // 3

// 添加元素
fruits.push("葡萄");     // 末尾添加
fruits.unshift("草莓");  // 开头添加

// 删除元素
fruits.pop();            // 删除最后一个
fruits.shift();          // 删除第一个

// 遍历数组
fruits.forEach(function(fruit) {
    console.log(fruit);
});

2.3 类型转换

隐式转换(自动转换)
javascript 复制代码
// 数字转字符串
let num = 10;
let str = num + "";  // "10"(加空字符串)

// 字符串转数字
let str2 = "20";
let num2 = +str2;    // 20(一元加号)
let num3 = str2 * 1; // 20(乘法)

// 布尔值转换
let bool = !!str2;   // true(双重取反)
显式转换(手动转换)
javascript 复制代码
// 转字符串
String(123);         // "123"
(123).toString();    // "123"

// 转数字
Number("123");       // 123
parseInt("123.45");  // 123(整数)
parseFloat("123.45"); // 123.45(小数)

// 转布尔值
Boolean(1);          // true
Boolean(0);          // false

2.4 类型检查

javascript 复制代码
// typeof 运算符
typeof 123;          // "number"
typeof "hello";      // "string"
typeof true;         // "boolean"
typeof undefined;    // "undefined"
typeof null;         // "object"(bug)
typeof {};           // "object"
typeof [];           // "object"(数组也是对象)

// instanceof 运算符(检查对象类型)
[] instanceof Array;     // true
{} instanceof Object;    // true

// Array.isArray()(检查是否为数组)
Array.isArray([]);       // true
Array.isArray({});       // false

三、运算符

3.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(取余)
console.log(a ** b); // 1000(幂运算,ES2016)

// 自增自减
let x = 5;
x++;  // x = 6(后置)
++x;  // x = 7(前置)
x--;  // x = 6(后置)
--x;  // x = 5(前置)

// 前置和后置的区别
let y = 5;
let result1 = ++y;  // y = 6, result1 = 6(先自增,再赋值)
let z = 5;
let result2 = z++;  // z = 6, result2 = 5(先赋值,再自增)

3.2 赋值运算符

javascript 复制代码
let x = 10;

x += 5;  // x = x + 5 = 15
x -= 3;  // x = x - 3 = 12
x *= 2;  // x = x * 2 = 24
x /= 4;  // x = x / 4 = 6
x %= 5;  // x = x % 5 = 1

3.3 比较运算符

javascript 复制代码
let a = 5;
let b = "5";

// 相等比较
console.log(a == b);   // true(值相等,类型不同也会相等)
console.log(a === b); // false(严格相等,值和类型都要相等)
console.log(a != b);   // false(值不相等)
console.log(a !== b);  // true(严格不相等)

// 大小比较
console.log(5 > 3);    // true
console.log(5 < 3);    // false
console.log(5 >= 5);   // true
console.log(5 <= 3);   // false

// 推荐使用严格相等(===)和严格不相等(!==)

3.4 逻辑运算符

javascript 复制代码
let x = 5;
let y = 10;

// 逻辑与(AND)
console.log(x > 0 && y > 0);  // true(两个都为 true)
console.log(x > 0 && y < 0);  // false(有一个为 false)

// 逻辑或(OR)
console.log(x > 0 || y < 0);  // true(有一个为 true)
console.log(x < 0 || y < 0);  // false(两个都为 false)

// 逻辑非(NOT)
console.log(!true);   // false
console.log(!false);  // true

// 短路求值
let result = x > 0 && y++;  // y++ 会执行(因为 x > 0 为 true)
let result2 = x < 0 && y++; // y++ 不会执行(短路)

3.5 三元运算符(条件运算符)

javascript 复制代码
let age = 20;
let status = age >= 18 ? "成年人" : "未成年人";
console.log(status);  // "成年人"

// 等价于
let status2;
if (age >= 18) {
    status2 = "成年人";
} else {
    status2 = "未成年人";
}

// 嵌套三元运算符
let score = 85;
let grade = score >= 90 ? "优秀" : 
            score >= 80 ? "良好" : 
            score >= 60 ? "及格" : "不及格";
console.log(grade);  // "良好"

3.6 其他运算符

javascript 复制代码
// 空值合并运算符(??,ES2020)
let name = null;
let displayName = name ?? "匿名";  // "匿名"(如果 name 为 null 或 undefined)

// 可选链运算符(?.,ES2020)
let user = {
    name: "张三",
    address: {
        city: "北京"
    }
};
console.log(user.address?.city);      // "北京"
console.log(user.address?.zipCode);  // undefined(不会报错)

// 展开运算符(...,ES6)
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];  // [1, 2, 3, 4, 5]

let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 };  // { a: 1, b: 2, c: 3 }

四、流程控制

4.1 if 语句

javascript 复制代码
let age = 20;

// 单分支
if (age >= 18) {
    console.log("成年人");
}

// 双分支
if (age >= 18) {
    console.log("成年人");
} else {
    console.log("未成年人");
}

// 多分支
if (age < 13) {
    console.log("儿童");
} else if (age < 18) {
    console.log("青少年");
} else if (age < 60) {
    console.log("成年人");
} else {
    console.log("老年人");
}

4.2 switch 语句

javascript 复制代码
let day = 3;
let dayName;

switch (day) {
    case 1:
        dayName = "星期一";
        break;
    case 2:
        dayName = "星期二";
        break;
    case 3:
        dayName = "星期三";
        break;
    case 4:
        dayName = "星期四";
        break;
    case 5:
        dayName = "星期五";
        break;
    case 6:
    case 7:
        dayName = "周末";
        break;
    default:
        dayName = "未知";
}

console.log(dayName);  // "星期三"

// ⚠️ 注意:必须使用 break,否则会"穿透"到下一个 case

4.3 for 循环

javascript 复制代码
// 传统 for 循环
for (let i = 0; i < 5; i++) {
    console.log(i);  // 0, 1, 2, 3, 4
}

// for...in 循环(遍历对象属性)
let person = { name: "张三", age: 20, city: "北京" };
for (let key in person) {
    console.log(key + ": " + person[key]);
}
// 输出:
// name: 张三
// age: 20
// city: 北京

// for...of 循环(遍历数组元素,ES6)
let fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
    console.log(fruit);
}
// 输出:
// 苹果
// 香蕉
// 橙子

4.4 while 循环

javascript 复制代码
// while 循环
let i = 0;
while (i < 5) {
    console.log(i);  // 0, 1, 2, 3, 4
    i++;
}

// do...while 循环(至少执行一次)
let j = 0;
do {
    console.log(j);  // 0, 1, 2, 3, 4
    j++;
} while (j < 5);

4.5 循环控制

javascript 复制代码
// break:跳出循环
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        break;  // 当 i = 5 时跳出循环
    }
    console.log(i);  // 0, 1, 2, 3, 4
}

// continue:跳过本次循环
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        continue;  // 跳过 i = 5 这次循环
    }
    console.log(i);  // 0, 1, 2, 3, 4, 6, 7, 8, 9
}

// 标签(label):跳出多层循环
outer: for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
        if (i === 1 && j === 1) {
            break outer;  // 跳出外层循环
        }
        console.log(i, j);
    }
}

五、函数

5.1 函数声明

javascript 复制代码
// 函数声明
function greet(name) {
    return "你好," + name + "!";
}

console.log(greet("张三"));  // "你好,张三!"

// 函数表达式
const greet2 = function(name) {
    return "你好," + name + "!";
};

// 箭头函数(ES6,推荐)
const greet3 = (name) => {
    return "你好," + name + "!";
};

// 箭头函数简化(单行)
const greet4 = (name) => "你好," + name + "!";

// 箭头函数简化(单个参数)
const greet5 = name => "你好," + name + "!";

5.2 函数参数

javascript 复制代码
// 默认参数(ES6)
function greet(name = "匿名") {
    return "你好," + name + "!";
}

console.log(greet());        // "你好,匿名!"
console.log(greet("张三"));  // "你好,张三!"

// 剩余参数(ES6)
function sum(...numbers) {
    let total = 0;
    for (let num of numbers) {
        total += num;
    }
    return total;
}

console.log(sum(1, 2, 3));        // 6
console.log(sum(1, 2, 3, 4, 5)); // 15

// 参数解构(ES6)
function greetUser({ name, age }) {
    return `你好,${name},你今年${age}岁!`;
}

console.log(greetUser({ name: "张三", age: 20 }));  // "你好,张三,你今年20岁!"

5.3 返回值

javascript 复制代码
// 有返回值
function add(a, b) {
    return a + b;
}

let result = add(3, 5);  // 8

// 无返回值(返回 undefined)
function sayHello(name) {
    console.log("你好," + name);
    // 没有 return,默认返回 undefined
}

let result2 = sayHello("张三");  // undefined

// 提前返回
function checkAge(age) {
    if (age < 0) {
        return "年龄不能为负数";
    }
    if (age < 18) {
        return "未成年人";
    }
    return "成年人";
}

5.4 作用域

javascript 复制代码
// 全局作用域
let globalVar = "全局变量";

function test() {
    // 函数作用域
    let localVar = "局部变量";
    console.log(globalVar);  // "全局变量"(可以访问全局变量)
    console.log(localVar);   // "局部变量"
}

test();
console.log(globalVar);  // "全局变量"
console.log(localVar);   // ❌ 报错:localVar is not defined

// 块级作用域(let、const)
if (true) {
    let blockVar = "块级变量";
    console.log(blockVar);  // "块级变量"
}
console.log(blockVar);  // ❌ 报错:blockVar is not defined

// var 没有块级作用域(不推荐)
if (true) {
    var oldVar = "旧变量";
}
console.log(oldVar);  // "旧变量"(可以访问)

5.5 闭包

javascript 复制代码
// 闭包:函数可以访问外部作用域的变量
function outer() {
    let count = 0;
    
    function inner() {
        count++;
        return count;
    }
    
    return inner;
}

const counter = outer();
console.log(counter());  // 1
console.log(counter());  // 2
console.log(counter());  // 3

// 闭包的应用:私有变量
function createCounter() {
    let count = 0;
    
    return {
        increment: () => ++count,
        decrement: () => --count,
        getCount: () => count
    };
}

const myCounter = createCounter();
console.log(myCounter.increment());  // 1
console.log(myCounter.increment());  // 2
console.log(myCounter.getCount());   // 2

5.6 高阶函数

javascript 复制代码
// 函数作为参数
function processArray(arr, callback) {
    let result = [];
    for (let item of arr) {
        result.push(callback(item));
    }
    return result;
}

let numbers = [1, 2, 3, 4, 5];
let doubled = processArray(numbers, x => x * 2);
console.log(doubled);  // [2, 4, 6, 8, 10]

// 函数作为返回值
function multiplyBy(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = multiplyBy(2);
const triple = multiplyBy(3);

console.log(double(5));  // 10
console.log(triple(5));  // 15

5.7 数组方法(函数式编程)

javascript 复制代码
let numbers = [1, 2, 3, 4, 5];

// map:映射(转换每个元素)
let doubled = numbers.map(x => x * 2);
console.log(doubled);  // [2, 4, 6, 8, 10]

// filter:过滤(筛选元素)
let evens = numbers.filter(x => x % 2 === 0);
console.log(evens);  // [2, 4]

// reduce:归约(累积计算)
let sum = numbers.reduce((acc, x) => acc + x, 0);
console.log(sum);  // 15

// forEach:遍历(执行操作)
numbers.forEach(x => console.log(x));  // 1, 2, 3, 4, 5

// find:查找(返回第一个匹配的元素)
let found = numbers.find(x => x > 3);
console.log(found);  // 4

// some:检查(是否有元素满足条件)
let hasEven = numbers.some(x => x % 2 === 0);
console.log(hasEven);  // true

// every:检查(是否所有元素都满足条件)
let allPositive = numbers.every(x => x > 0);
console.log(allPositive);  // true

六、对象与数组

6.1 对象(Object)

javascript 复制代码
// 创建对象
let user = {
    name: "张三",
    age: 20,
    email: "zhangsan@example.com",
    sayHello: function() {
        return "你好,我是" + this.name;
    }
};

// 访问属性
console.log(user.name);           // "张三"
console.log(user["age"]);         // 20
console.log(user.sayHello());     // "你好,我是张三"

// 添加属性
user.city = "北京";
user["country"] = "中国";

// 修改属性
user.age = 21;

// 删除属性
delete user.email;

// 检查属性是否存在
console.log("name" in user);      // true
console.log(user.hasOwnProperty("name"));  // true

// 遍历对象
for (let key in user) {
    console.log(key + ": " + user[key]);
}

// Object.keys()、Object.values()、Object.entries()
console.log(Object.keys(user));      // ["name", "age", "city", "country", "sayHello"]
console.log(Object.values(user));    // ["张三", 21, "北京", "中国", function...]
console.log(Object.entries(user));   // [["name", "张三"], ["age", 21], ...]

6.2 数组(Array)

javascript 复制代码
// 创建数组
let fruits = ["苹果", "香蕉", "橙子"];
let numbers = new Array(1, 2, 3);

// 访问元素
console.log(fruits[0]);        // "苹果"
console.log(fruits.length);    // 3

// 添加元素
fruits.push("葡萄");           // 末尾添加
fruits.unshift("草莓");        // 开头添加
fruits.splice(2, 0, "芒果");   // 索引 2 处插入

// 删除元素
fruits.pop();                  // 删除最后一个
fruits.shift();                // 删除第一个
fruits.splice(1, 1);           // 删除索引 1 的元素

// 查找元素
console.log(fruits.indexOf("香蕉"));  // 1(索引)
console.log(fruits.includes("苹果")); // true(是否存在)

// 数组方法
let numbers = [1, 2, 3, 4, 5];

// 切片(不改变原数组)
let slice = numbers.slice(1, 3);  // [2, 3]

// 连接(不改变原数组)
let combined = numbers.concat([6, 7]);  // [1, 2, 3, 4, 5, 6, 7]

// 反转(改变原数组)
numbers.reverse();  // [5, 4, 3, 2, 1]

// 排序(改变原数组)
let unsorted = [3, 1, 4, 1, 5];
unsorted.sort();  // [1, 1, 3, 4, 5]
unsorted.sort((a, b) => b - a);  // [5, 4, 3, 1, 1](降序)

6.3 解构赋值(ES6)

javascript 复制代码
// 数组解构
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);  // 1, 2, 3

let [x, , z] = [1, 2, 3];  // 跳过中间的元素
console.log(x, z);  // 1, 3

let [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first);  // 1
console.log(rest);   // [2, 3, 4, 5]

// 对象解构
let { name, age } = { name: "张三", age: 20, city: "北京" };
console.log(name, age);  // "张三", 20

let { name: userName, age: userAge } = { name: "张三", age: 20 };
console.log(userName, userAge);  // "张三", 20(重命名)

// 默认值
let { name = "匿名", age = 0 } = { name: "张三" };
console.log(name, age);  // "张三", 0

// 嵌套解构
let user = {
    name: "张三",
    address: {
        city: "北京",
        zipCode: "100000"
    }
};
let { address: { city } } = user;
console.log(city);  // "北京"

七、字符串操作

7.1 字符串方法

javascript 复制代码
let text = "Hello World";

// 长度
console.log(text.length);  // 11

// 大小写转换
console.log(text.toUpperCase());  // "HELLO WORLD"
console.log(text.toLowerCase());  // "hello world"

// 查找
console.log(text.indexOf("World"));     // 6(首次出现的位置)
console.log(text.lastIndexOf("o"));     // 7(最后出现的位置)
console.log(text.includes("World"));     // true(是否包含)
console.log(text.startsWith("Hello"));  // true(是否以...开头)
console.log(text.endsWith("World"));    // true(是否以...结尾)

// 截取
console.log(text.substring(0, 5));      // "Hello"(开始索引,结束索引)
console.log(text.slice(0, 5));          // "Hello"(开始索引,结束索引)
console.log(text.slice(-5));            // "World"(负数表示从末尾开始)

// 替换
console.log(text.replace("World", "JavaScript"));  // "Hello JavaScript"
console.log(text.replaceAll("l", "L"));           // "HeLLo WorLd"(ES2021)

// 分割
let words = text.split(" ");  // ["Hello", "World"]
let chars = text.split("");   // ["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d"]

// 去除空白
let spaced = "  Hello World  ";
console.log(spaced.trim());        // "Hello World"(去除首尾空白)
console.log(spaced.trimStart());   // "Hello World  "(去除开头空白)
console.log(spaced.trimEnd());     // "  Hello World"(去除结尾空白)

// 重复
console.log("Hello".repeat(3));  // "HelloHelloHello"

7.2 模板字符串(ES6)

javascript 复制代码
let name = "张三";
let age = 20;

// 传统方式
let message1 = "你好,我是" + name + ",今年" + age + "岁";

// 模板字符串(推荐)
let message2 = `你好,我是${name},今年${age}岁`;

// 多行字符串
let multiLine = `
    第一行
    第二行
    第三行
`;

// 表达式
let a = 5;
let b = 10;
let result = `${a} + ${b} = ${a + b}`;  // "5 + 10 = 15"

// 函数调用
function greet(name) {
    return `你好,${name}!`;
}
let greeting = `${greet("张三")}`;  // "你好,张三!"

八、ES6+ 新特性

8.1 let 和 const

javascript 复制代码
// let:块级作用域变量
if (true) {
    let x = 10;
}
console.log(x);  // ❌ 报错:x is not defined

// const:常量
const PI = 3.14159;
PI = 3.14;  // ❌ 报错:Assignment to constant variable

// const 对象可以修改属性
const user = { name: "张三" };
user.name = "李四";  // ✅ 可以
user = {};           // ❌ 不可以(不能重新赋值)

8.2 箭头函数

javascript 复制代码
// 传统函数
function add(a, b) {
    return a + b;
}

// 箭头函数
const add2 = (a, b) => a + b;

// 箭头函数的特点
let obj = {
    name: "张三",
    // 传统函数:this 指向 obj
    sayHello1: function() {
        console.log("你好," + this.name);
    },
    // 箭头函数:this 指向外层作用域(window)
    sayHello2: () => {
        console.log("你好," + this.name);  // undefined
    }
};

obj.sayHello1();  // "你好,张三"
obj.sayHello2();  // "你好,undefined"

8.3 解构赋值

javascript 复制代码
// 数组解构
let [a, b] = [1, 2];

// 对象解构
let { name, age } = { name: "张三", age: 20 };

// 函数参数解构
function greet({ name, age }) {
    return `你好,${name},${age}岁`;
}

8.4 展开运算符

javascript 复制代码
// 数组展开
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];  // [1, 2, 3, 4, 5]

// 对象展开
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 };  // { a: 1, b: 2, c: 3 }

// 函数参数展开
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3);  // 6

8.5 Promise 和 async/await

javascript 复制代码
// Promise
function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("数据获取成功");
        }, 1000);
    });
}

fetchData()
    .then(data => console.log(data))
    .catch(error => console.error(error));

// async/await(ES2017)
async function getData() {
    try {
        let data = await fetchData();
        console.log(data);
    } catch (error) {
        console.error(error);
    }
}

8.6 类(Class,ES6)

javascript 复制代码
// 类定义
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    sayHello() {
        return `你好,我是${this.name},${this.age}岁`;
    }
}

// 创建实例
let person = new Person("张三", 20);
console.log(person.sayHello());  // "你好,我是张三,20岁"

// 继承
class Student extends Person {
    constructor(name, age, school) {
        super(name, age);
        this.school = school;
    }
    
    study() {
        return `${this.name}在${this.school}学习`;
    }
}

let student = new Student("李四", 18, "北京大学");
console.log(student.sayHello());  // "你好,我是李四,18岁"
console.log(student.study());     // "李四在北京大学学习"

九、异步编程

9.1 回调函数

javascript 复制代码
// 回调函数(Callback)
function fetchData(callback) {
    setTimeout(() => {
        callback("数据获取成功");
    }, 1000);
}

fetchData(function(data) {
    console.log(data);
});

// 回调地狱(不推荐)
fetchData(function(data1) {
    fetchData(function(data2) {
        fetchData(function(data3) {
            console.log(data1, data2, data3);
        });
    });
});

9.2 Promise

javascript 复制代码
// Promise 创建
let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        let success = true;
        if (success) {
            resolve("操作成功");
        } else {
            reject("操作失败");
        }
    }, 1000);
});

// Promise 使用
promise
    .then(result => {
        console.log(result);  // "操作成功"
        return "下一步";
    })
    .then(result => {
        console.log(result);  // "下一步"
    })
    .catch(error => {
        console.error(error);  // "操作失败"
    })
    .finally(() => {
        console.log("完成");  // 无论成功失败都会执行
    });

// Promise.all:等待所有 Promise 完成
Promise.all([
    fetchData1(),
    fetchData2(),
    fetchData3()
])
.then(results => {
    console.log(results);  // [结果1, 结果2, 结果3]
});

// Promise.race:第一个完成的 Promise
Promise.race([
    fetchData1(),
    fetchData2()
])
.then(result => {
    console.log(result);  // 第一个完成的结果
});

9.3 async/await

javascript 复制代码
// async/await(推荐)
async function fetchUserData() {
    try {
        let user = await fetchUser();
        let posts = await fetchPosts(user.id);
        let comments = await fetchComments(posts[0].id);
        return { user, posts, comments };
    } catch (error) {
        console.error("错误:", error);
        throw error;
    }
}

fetchUserData()
    .then(data => console.log(data))
    .catch(error => console.error(error));

// 并行执行(使用 Promise.all)
async function fetchAllData() {
    let [user, posts, comments] = await Promise.all([
        fetchUser(),
        fetchPosts(),
        fetchComments()
    ]);
    return { user, posts, comments };
}

9.4 Fetch API

javascript 复制代码
// Fetch API(现代浏览器)
fetch("https://api.example.com/data")
    .then(response => {
        if (!response.ok) {
            throw new Error("网络错误");
        }
        return response.json();
    })
    .then(data => {
        console.log(data);
    })
    .catch(error => {
        console.error("错误:", error);
    });

// 使用 async/await
async function fetchData() {
    try {
        let response = await fetch("https://api.example.com/data");
        if (!response.ok) {
            throw new Error("网络错误");
        }
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("错误:", error);
    }
}

// POST 请求
async function postData(url, data) {
    let response = await fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(data)
    });
    return response.json();
}

十、DOM 操作

10.1 选择元素

javascript 复制代码
// 选择单个元素
let element = document.getElementById("myId");
let element2 = document.querySelector(".myClass");
let element3 = document.querySelector("#myId");

// 选择多个元素
let elements = document.getElementsByClassName("myClass");
let elements2 = document.getElementsByTagName("div");
let elements3 = document.querySelectorAll(".myClass");

// 遍历元素
elements3.forEach(element => {
    console.log(element);
});

10.2 修改内容

javascript 复制代码
// 修改文本内容
let element = document.getElementById("myId");
element.textContent = "新文本";
element.innerText = "新文本";
element.innerHTML = "<strong>新文本</strong>";

// 修改属性
element.setAttribute("class", "newClass");
element.className = "newClass";
element.id = "newId";

// 修改样式
element.style.color = "red";
element.style.fontSize = "20px";
element.style.backgroundColor = "yellow";

10.3 创建和删除元素

javascript 复制代码
// 创建元素
let newDiv = document.createElement("div");
newDiv.textContent = "新元素";
newDiv.className = "myClass";

// 添加到页面
let parent = document.getElementById("parent");
parent.appendChild(newDiv);

// 插入元素
let beforeElement = document.getElementById("before");
parent.insertBefore(newDiv, beforeElement);

// 删除元素
parent.removeChild(newDiv);
newDiv.remove();  // 现代方式

10.4 事件处理

javascript 复制代码
// 添加事件监听器
let button = document.getElementById("myButton");

// 方式一:addEventListener(推荐)
button.addEventListener("click", function() {
    console.log("按钮被点击了");
});

// 方式二:onclick(不推荐)
button.onclick = function() {
    console.log("按钮被点击了");
};

// 事件对象
button.addEventListener("click", function(event) {
    console.log(event.target);      // 触发事件的元素
    console.log(event.type);        // 事件类型("click")
    event.preventDefault();          // 阻止默认行为
    event.stopPropagation();        // 阻止事件冒泡
});

// 常见事件
element.addEventListener("click", handler);      // 点击
element.addEventListener("mouseenter", handler);  // 鼠标进入
element.addEventListener("mouseleave", handler); // 鼠标离开
element.addEventListener("input", handler);       // 输入
element.addEventListener("submit", handler);     // 提交表单
element.addEventListener("load", handler);        // 加载完成

十一、常见错误与调试

11.1 常见错误

javascript 复制代码
// 1. 未定义变量
console.log(undefinedVar);  // ❌ ReferenceError: undefinedVar is not defined

// 2. 类型错误
let num = 10;
num.toUpperCase();  // ❌ TypeError: num.toUpperCase is not a function

// 3. 语法错误
let x = 10;  // ❌ SyntaxError: Unexpected token

// 4. 空值错误
let user = null;
console.log(user.name);  // ❌ TypeError: Cannot read property 'name' of null

// 5. 作用域错误
function test() {
    if (true) {
        var x = 10;
    }
    console.log(x);  // 10(var 没有块级作用域)
}

11.2 调试技巧

javascript 复制代码
// console.log:输出信息
console.log("变量值:", variable);

// console.error:输出错误
console.error("错误信息:", error);

// console.warn:输出警告
console.warn("警告信息:", warning);

// console.table:表格形式输出
let users = [
    { name: "张三", age: 20 },
    { name: "李四", age: 25 }
];
console.table(users);

// debugger:断点调试
function complexFunction() {
    debugger;  // 浏览器会在这里暂停
    // 代码...
}

// try...catch:错误处理
try {
    // 可能出错的代码
    let result = riskyOperation();
} catch (error) {
    // 错误处理
    console.error("错误:", error.message);
} finally {
    // 无论是否出错都会执行
    console.log("完成");
}

十二、最佳实践

12.1 代码风格

javascript 复制代码
// ✅ 使用 const 和 let,避免 var
const PI = 3.14159;
let count = 0;

// ✅ 使用箭头函数
const add = (a, b) => a + b;

// ✅ 使用模板字符串
const message = `你好,${name}!`;

// ✅ 使用解构赋值
const { name, age } = user;

// ✅ 使用严格相等
if (x === y) {  // 而不是 x == y
    // ...
}

// ✅ 使用有意义的变量名
const userName = "张三";  // 而不是 u 或 n

12.2 性能优化

javascript 复制代码
// ✅ 缓存 DOM 查询
const element = document.getElementById("myId");
// 多次使用 element,而不是重复查询

// ✅ 使用事件委托
document.addEventListener("click", function(event) {
    if (event.target.classList.contains("button")) {
        // 处理点击
    }
});

// ✅ 避免全局变量
(function() {
    // 局部作用域
    let localVar = "局部变量";
})();

// ✅ 使用数组方法而不是循环
let doubled = numbers.map(x => x * 2);  // 而不是 for 循环

12.3 代码组织

javascript 复制代码
// ✅ 模块化(ES6 Modules)
// math.js
export function add(a, b) {
    return a + b;
}

export function subtract(a, b) {
    return a - b;
}

// main.js
import { add, subtract } from './math.js';
console.log(add(1, 2));  // 3

// ✅ 使用对象组织代码
const Calculator = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b
};

// ✅ 使用类组织代码
class Calculator {
    add(a, b) {
        return a + b;
    }
    subtract(a, b) {
        return a - b;
    }
}

十三、总结

13.1 核心概念

  1. 变量 :使用 letconst,避免 var
  2. 数据类型:8 种类型(Number、String、Boolean、Undefined、Null、Symbol、BigInt、Object)
  3. 函数:函数声明、函数表达式、箭头函数
  4. 对象和数组:解构赋值、展开运算符
  5. 异步编程:Promise、async/await

13.2 学习路径

  1. 基础语法:变量、数据类型、运算符、流程控制
  2. 函数:函数定义、参数、返回值、作用域
  3. 对象和数组:创建、访问、修改、遍历
  4. ES6+ 特性:let/const、箭头函数、解构、模板字符串
  5. 异步编程:Promise、async/await
  6. DOM 操作:选择元素、修改内容、事件处理

13.3 推荐资源


希望这篇教程能帮助你掌握 JavaScript!多写代码,多实践,才能熟练掌握。

相关推荐
岱宗夫up1 小时前
FastAPI入门(上篇):快速构建高性能Python Web API
开发语言·前端·python·fastapi
Dxy12393102162 小时前
中文乱码恢复方案
开发语言·python
浅念-2 小时前
C/C++内存管理
c语言·开发语言·c++·经验分享·笔记·学习
回敲代码的猴子2 小时前
2月8日上机
开发语言·c++·算法
rongyili882 小时前
Dify 外部知识库集成 Milvus 实战指南
开发语言·python·milvus
IT猿手3 小时前
MOEA/D(基于分解的多目标进化算法)求解46个多目标函数及一个工程应用,包含四种评价指标,MATLAB代码
开发语言·算法·matlab·多目标算法
野犬寒鸦3 小时前
从零起步学习并发编程 || 第九章:Future 类详解及CompletableFuture 类在项目实战中的应用
java·开发语言·jvm·数据库·后端·学习
南 阳3 小时前
Python从入门到精通day34
开发语言·python
前路不黑暗@3 小时前
Java项目:Java脚手架项目的统一模块的封装(四)
java·开发语言·spring boot·笔记·学习·spring cloud·maven