JavaScript参考手册

完整的JavaScript API参考,包含语法、示例、浏览器兼容性和ECMAScript规范详解

JavaScript参考手册

本参考手册提供了JavaScript核心语法、内置对象和方法的完整参考,包含详细的语法说明、使用示例和浏览器兼容性信息。使用搜索功能快速查找您需要的内容。

JavaScript版本历史

版本 发布年份 主要特性 ECMAScript版本
ES1 1997 基础语法、类型、函数 ECMA-262 1st Edition
ES3 1999 正则表达式、异常处理 ECMA-262 3rd Edition
ES5 2009 严格模式、JSON、数组方法 ECMA-262 5th Edition
ES6/ES2015 2015 类、模块、箭头函数、Promise ECMA-262 6th Edition
ES2016 2016 数组includes、指数运算符 ECMA-262 7th Edition
ES2017 2017 async/await、字符串填充 ECMA-262 8th Edition
ES2018 2018 Rest/Spread属性、异步迭代 ECMA-262 9th Edition
ES2019 2019 数组flat、Object.fromEntries ECMA-262 10th Edition
ES2020 2020 可选链、空值合并、BigInt ECMA-262 11th Edition
ES2021 2021 字符串replaceAll、逻辑赋值 ECMA-262 12th Edition
ES2022 2022 类字段、顶层await、数组at ECMA-262 13th Edition

内置对象

JavaScript提供了一系列内置对象,用于处理各种数据类型和执行常见操作。这些对象在全局作用域中可用,无需导入。

全局对象

Object
Function
Array
String
Number
Boolean
Date
Math
RegExp
Error
Promise
Map
Set
Symbol
WeakMap
WeakSet
Proxy
Reflect
JSON
Intl

Object

Object是JavaScript中所有对象的基类。几乎所有对象都是Object的实例。

方法/属性 描述 语法 返回值 ES版本
Object.keys() 返回对象自身可枚举属性的数组 Object.keys(obj) Array ES5
Object.values() 返回对象自身可枚举属性值的数组 Object.values(obj) Array ES2017
Object.entries() 返回对象自身可枚举属性的键值对数组 Object.entries(obj) Array ES2017
Object.assign() 将一个或多个源对象复制到目标对象 Object.assign(target, ...sources) Object ES6
Object.freeze() 冻结对象,使其不可修改 Object.freeze(obj) Object ES5
Object.seal() 密封对象,防止添加/删除属性 Object.seal(obj) Object ES5
Object.create() 使用指定原型创建新对象 Object.create(proto) Object ES5
Object.defineProperty() 定义对象的新属性或修改现有属性 Object.defineProperty(obj, prop, descriptor) Object ES5
Object.getPrototypeOf() 返回指定对象的原型 Object.getPrototypeOf(obj) Object ES5
Object.hasOwn() 检查对象是否有指定属性(不继承) Object.hasOwn(obj, prop) Boolean ES2022

Object方法示例

Object方法使用示例
const person = {
    name: '张三',
    age: 25,
    city: '北京'
};

// Object.keys()
console.log(Object.keys(person)); // ['name', 'age', 'city']

// Object.values()
console.log(Object.values(person)); // ['张三', 25, '北京']

// Object.entries()
console.log(Object.entries(person)); 
// [['name', '张三'], ['age', 25], ['city', '北京']]

// Object.assign()
const newPerson = Object.assign({}, person, { age: 26, gender: '男' });
console.log(newPerson); 
// { name: '张三', age: 26, city: '北京', gender: '男' }

// Object.freeze()
Object.freeze(person);
person.age = 30; // 严格模式下会报错
console.log(person.age); // 25 (值未改变)

// Object.create()
const student = Object.create(person);
student.grade = 'A';
console.log(student.name); // '张三' (继承自person)
console.log(student.grade); // 'A'

// Object.defineProperty()
Object.defineProperty(person, 'country', {
    value: '中国',
    writable: false,
    enumerable: true,
    configurable: false
});
console.log(person.country); // '中国'

// Object.hasOwn()
console.log(Object.hasOwn(person, 'name')); // true
console.log(Object.hasOwn(person, 'toString')); // false (继承的方法)

Math

Math对象提供数学常数和函数。Math的所有属性和方法都是静态的。

方法/属性 描述 语法 返回值 ES版本
Math.PI 圆周率π Math.PI Number ES1
Math.E 自然对数的底数e Math.E Number ES1
Math.random() 返回0到1之间的随机数 Math.random() Number ES1
Math.floor() 向下取整 Math.floor(x) Number ES1
Math.ceil() 向上取整 Math.ceil(x) Number ES1
Math.round() 四舍五入 Math.round(x) Number ES1
Math.max() 返回最大值 Math.max(...values) Number ES1
Math.min() 返回最小值 Math.min(...values) Number ES1
Math.pow() 幂运算 Math.pow(base, exponent) Number ES1
Math.sqrt() 平方根 Math.sqrt(x) Number ES1
Math.abs() 绝对值 Math.abs(x) Number ES1
Math.sin() 正弦函数 Math.sin(x) Number ES1
Math.cos() 余弦函数 Math.cos(x) Number ES1
Math.tan() 正切函数 Math.tan(x) Number ES1
Math.log() 自然对数 Math.log(x) Number ES1
Math.exp() e的指数 Math.exp(x) Number ES1

Math方法示例

Math方法使用示例
// 数学常数
console.log(Math.PI); // 3.141592653589793
console.log(Math.E);  // 2.718281828459045

// 随机数
console.log(Math.random()); // 0.123456789 (随机值)
console.log(Math.floor(Math.random() * 100) + 1); // 1-100的随机整数

// 取整
console.log(Math.floor(3.7)); // 3
console.log(Math.ceil(3.2));  // 4
console.log(Math.round(3.5)); // 4

// 最大值和最小值
console.log(Math.max(1, 2, 3, 4, 5)); // 5
console.log(Math.min(1, 2, 3, 4, 5)); // 1

// 幂运算和平方根
console.log(Math.pow(2, 3)); // 8
console.log(Math.sqrt(16));   // 4

// 三角函数 (参数为弧度)
console.log(Math.sin(Math.PI / 2)); // 1
console.log(Math.cos(Math.PI));     // -1
console.log(Math.tan(Math.PI / 4)); // 1

// 对数和指数
console.log(Math.log(Math.E)); // 1
console.log(Math.exp(1));      // 2.718281828459045

// 实际应用:生成随机颜色
function getRandomColor() {
    const r = Math.floor(Math.random() * 256);
    const g = Math.floor(Math.random() * 256);
    const b = Math.floor(Math.random() * 256);
    return `rgb(${r}, ${g}, ${b})`;
}

console.log(getRandomColor()); // rgb(123, 45, 67)

JSON

JSON对象用于解析和序列化JSON数据。

方法 描述 语法 返回值 ES版本
JSON.parse() 解析JSON字符串为JavaScript对象 JSON.parse(text, reviver) Object/Array ES5
JSON.stringify() 将JavaScript值转换为JSON字符串 JSON.stringify(value, replacer, space) String ES5

JSON方法示例

JSON方法使用示例
const person = {
    name: '张三',
    age: 25,
    hobbies: ['读书', '编程', '运动'],
    address: {
        city: '北京',
        country: '中国'
    },
    isStudent: false,
    birthDate: new Date('1998-05-15'),
    // 函数不会被序列化
    sayHello: function() {
        return `你好,我是${this.name}`;
    }
};

// JSON.stringify() - 序列化为JSON字符串
const jsonString = JSON.stringify(person);
console.log(jsonString);
// {"name":"张三","age":25,"hobbies":["读书","编程","运动"],"address":{"city":"北京","country":"中国"},"isStudent":false,"birthDate":"1998-05-15T00:00:00.000Z"}

// 使用replacer函数
const filteredJson = JSON.stringify(person, (key, value) => {
    if (key === 'age') return undefined; // 过滤age属性
    return value;
});
console.log(filteredJson);
// {"name":"张三","hobbies":["读书","编程","运动"],"address":{"city":"北京","country":"中国"},"isStudent":false,"birthDate":"1998-05-15T00:00:00.000Z"}

// 格式化输出
const prettyJson = JSON.stringify(person, null, 2);
console.log(prettyJson);
/*
{
  "name": "张三",
  "age": 25,
  "hobbies": [
    "读书",
    "编程",
    "运动"
  ],
  ...
}
*/

// JSON.parse() - 解析JSON字符串
const parsedObject = JSON.parse(jsonString);
console.log(parsedObject.name); // '张三'
console.log(parsedObject.hobbies); // ['读书', '编程', '运动']

// 使用reviver函数
const revivedObject = JSON.parse(jsonString, (key, value) => {
    if (key === 'birthDate') return new Date(value);
    return value;
});
console.log(revivedObject.birthDate instanceof Date); // true

// 错误处理
try {
    const invalidJson = '{"name": "张三", "age": }';
    const result = JSON.parse(invalidJson);
} catch (error) {
    console.error('JSON解析错误:', error.message);
}

数组方法

Array对象提供了处理数组的各种方法,包括修改、遍历、搜索和转换数组的方法。

常用数组方法

方法 描述 语法 返回值 改变原数组 ES版本
push() 在数组末尾添加元素 arr.push(...items) 新长度 ES1
pop() 移除并返回最后一个元素 arr.pop() 元素 ES1
shift() 移除并返回第一个元素 arr.shift() 元素 ES1
unshift() 在数组开头添加元素 arr.unshift(...items) 新长度 ES1
concat() 合并数组 arr.concat(...values) 新数组 ES3
slice() 返回数组的一部分 arr.slice(start, end) 新数组 ES3
splice() 添加/删除元素 arr.splice(start, deleteCount, ...items) 被删除元素 ES3
indexOf() 查找元素索引 arr.indexOf(searchElement, fromIndex) 索引/-1 ES5
lastIndexOf() 从后向前查找元素索引 arr.lastIndexOf(searchElement, fromIndex) 索引/-1 ES5
includes() 检查是否包含元素 arr.includes(searchElement, fromIndex) Boolean ES2016
join() 将数组元素连接为字符串 arr.join(separator) String ES1
reverse() 反转数组顺序 arr.reverse() 数组 ES1
sort() 数组排序 arr.sort(compareFunction) 数组 ES1

迭代方法

方法 描述 语法 返回值 ES版本
forEach() 对每个元素执行函数 arr.forEach(callback) undefined ES5
map() 对每个元素执行函数并返回新数组 arr.map(callback) 新数组 ES5
filter() 返回满足条件的元素组成的新数组 arr.filter(callback) 新数组 ES5
reduce() 将数组减少为单个值 arr.reduce(callback, initialValue) 任意类型 ES5
reduceRight() 从右向左将数组减少为单个值 arr.reduceRight(callback, initialValue) 任意类型 ES5
find() 返回第一个满足条件的元素 arr.find(callback) 元素/undefined ES6
findIndex() 返回第一个满足条件的元素索引 arr.findIndex(callback) 索引/-1 ES6
some() 检查是否有元素满足条件 arr.some(callback) Boolean ES5
every() 检查所有元素是否满足条件 arr.every(callback) Boolean ES5
flat() 将嵌套数组扁平化 arr.flat(depth) 新数组 ES2019
flatMap() 先映射后扁平化 arr.flatMap(callback) 新数组 ES2019

数组方法示例

数组方法综合示例
const numbers = [1, 2, 3, 4, 5, 6];
const fruits = ['苹果', '香蕉', '橙子', '葡萄'];
const mixed = [1, 'hello', true, { name: '张三' }, [7, 8, 9]];

// 基本操作
console.log(fruits.join(', ')); // '苹果, 香蕉, 橙子, 葡萄'
console.log(fruits.includes('香蕉')); // true
console.log(fruits.indexOf('橙子')); // 2

// 添加/删除元素
fruits.push('芒果');
console.log(fruits); // ['苹果', '香蕉', '橙子', '葡萄', '芒果']

const lastFruit = fruits.pop();
console.log(lastFruit); // '芒果'
console.log(fruits); // ['苹果', '香蕉', '橙子', '葡萄']

fruits.unshift('草莓');
console.log(fruits); // ['草莓', '苹果', '香蕉', '橙子', '葡萄']

const firstFruit = fruits.shift();
console.log(firstFruit); // '草莓'
console.log(fruits); // ['苹果', '香蕉', '橙子', '葡萄']

// 切片和拼接
const sliced = fruits.slice(1, 3);
console.log(sliced); // ['香蕉', '橙子']

fruits.splice(1, 2, '桃子', '梨子');
console.log(fruits); // ['苹果', '桃子', '梨子', '葡萄']

// 使用map转换数组
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10, 12]

// 使用filter过滤数组
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6]

// 使用reduce计算总和
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum); // 21

// 使用find查找元素
const firstEven = numbers.find(n => n % 2 === 0);
console.log(firstEven); // 2

// 使用some检查条件
const hasEven = numbers.some(n => n % 2 === 0);
console.log(hasEven); // true

// 使用every检查所有元素
const allPositive = numbers.every(n => n > 0);
console.log(allPositive); // true

// 扁平化数组
const nested = [1, [2, [3, [4]]]];
console.log(nested.flat()); // [1, 2, [3, [4]]]
console.log(nested.flat(2)); // [1, 2, 3, [4]]
console.log(nested.flat(Infinity)); // [1, 2, 3, 4]

// flatMap示例
const sentences = ['Hello world', 'JavaScript is awesome'];
const words = sentences.flatMap(sentence => sentence.split(' '));
console.log(words); // ['Hello', 'world', 'JavaScript', 'is', 'awesome']

// 链式调用
const result = numbers
    .filter(n => n % 2 === 0)
    .map(n => n * 3)
    .reduce((sum, n) => sum + n, 0);
    
console.log(result); // 36 (2*3 + 4*3 + 6*3)

// 排序
const randomNumbers = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(randomNumbers.sort()); // [1, 1, 2, 3, 4, 5, 6, 9]
console.log(randomNumbers.sort((a, b) => b - a)); // [9, 6, 5, 4, 3, 2, 1, 1]

// 反转
console.log(fruits.reverse()); // ['葡萄', '梨子', '桃子', '苹果']

字符串方法

String对象提供了处理文本的各种方法,包括搜索、提取、修改和转换字符串的方法。

常用字符串方法

方法 描述 语法 返回值 ES版本
length 字符串长度 str.length Number ES1
charAt() 返回指定位置的字符 str.charAt(index) String ES1
charCodeAt() 返回指定位置字符的Unicode编码 str.charCodeAt(index) Number ES1
indexOf() 返回子字符串首次出现的位置 str.indexOf(searchValue, fromIndex) 索引/-1 ES1
lastIndexOf() 返回子字符串最后出现的位置 str.lastIndexOf(searchValue, fromIndex) 索引/-1 ES1
slice() 提取字符串的一部分 str.slice(startIndex, endIndex) String ES3
substring() 提取字符串的一部分 str.substring(startIndex, endIndex) String ES1
substr() 从指定位置提取指定长度的字符串 str.substr(startIndex, length) String ES3
toUpperCase() 转换为大写 str.toUpperCase() String ES1
toLowerCase() 转换为小写 str.toLowerCase() String ES1
trim() 移除两端空白字符 str.trim() String ES5
trimStart() 移除开头空白字符 str.trimStart() String ES2019
trimEnd() 移除结尾空白字符 str.trimEnd() String ES2019
replace() 替换子字符串 str.replace(searchValue, replaceValue) String ES3
replaceAll() 替换所有匹配的子字符串 str.replaceAll(searchValue, replaceValue) String ES2021
split() 将字符串分割为数组 str.split(separator, limit) Array ES1
startsWith() 检查是否以指定字符串开头 str.startsWith(searchString, position) Boolean ES6
endsWith() 检查是否以指定字符串结尾 str.endsWith(searchString, length) Boolean ES6
includes() 检查是否包含指定字符串 str.includes(searchString, position) Boolean ES6
padStart() 在开头填充字符串 str.padStart(targetLength, padString) String ES2017
padEnd() 在结尾填充字符串 str.padEnd(targetLength, padString) String ES2017
repeat() 重复字符串指定次数 str.repeat(count) String ES6

字符串方法示例

字符串操作示例
const text = '  Hello, JavaScript World!  ';
const email = 'user@example.com';
const phone = '13800138000';
const multiline = `第一行
第二行
第三行`;

// 基本操作
console.log(text.length); // 28
console.log(text.trim()); // 'Hello, JavaScript World!'
console.log(text.trimStart()); // 'Hello, JavaScript World!  '
console.log(text.trimEnd()); // '  Hello, JavaScript World!'
console.log(text.toUpperCase()); // '  HELLO, JAVASCRIPT WORLD!  '
console.log(text.toLowerCase()); // '  hello, javascript world!  '

// 搜索和提取
console.log(text.indexOf('JavaScript')); // 9
console.log(text.lastIndexOf(' ')); // 24
console.log(text.charAt(5)); // 'H'
console.log(text.charCodeAt(5)); // 72 (H的Unicode)
console.log(text.slice(2, 7)); // 'Hello'
console.log(text.substring(2, 7)); // 'Hello'
console.log(text.substr(2, 5)); // 'Hello'

// 替换和分割
console.log(text.replace('JavaScript', 'JS')); // '  Hello, JS World!  '
console.log(text.replaceAll(' ', '-')); // '--Hello,-JavaScript-World!--'
console.log(text.split(' ')); // ['', '', 'Hello,', 'JavaScript', 'World!', '', '']

// 现代方法
console.log(text.includes('JavaScript')); // true
console.log(text.startsWith('  Hello')); // true
console.log(text.endsWith('World!  ')); // true

// 填充和重复
console.log('5'.padStart(3, '0')); // '005'
console.log('5'.padEnd(3, '0')); // '500'
console.log('Hi'.repeat(3)); // 'HiHiHi'

// 模板字符串 (ES6)
const name = '张三';
const age = 25;
const message = `我叫${name},今年${age}岁。`;
console.log(message); // '我叫张三,今年25岁。'

// 多行字符串
console.log(multiline);
/*
第一行
第二行
第三行
*/

// 实际应用:验证邮箱
function isValidEmail(email) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email.trim().toLowerCase());
}

console.log(isValidEmail('USER@EXAMPLE.COM')); // true
console.log(isValidEmail('invalid-email')); // false

// 实际应用:格式化手机号
function formatPhoneNumber(phone) {
    const cleaned = phone.replace(/\D/g, '');
    const match = cleaned.match(/^(\d{3})(\d{4})(\d{4})$/);
    if (match) {
        return `${match[1]} ${match[2]} ${match[3]}`;
    }
    return phone;
}

console.log(formatPhoneNumber('13800138000')); // '138 0013 8000'

// 实际应用:提取URL参数
function getUrlParams(url) {
    const params = {};
    const urlObj = new URL(url);
    urlObj.searchParams.forEach((value, key) => {
        params[key] = value;
    });
    return params;
}

const testUrl = 'https://example.com?name=张三&age=25&city=北京';
console.log(getUrlParams(testUrl)); // { name: '张三', age: '25', city: '北京' }

ES6+新特性参考

ECMAScript 2015 (ES6) 及后续版本引入了许多新特性,使JavaScript更现代化、更强大。这些特性提高了开发效率和代码质量。

ES6+主要特性

特性 描述 语法示例 ES版本
let/const 块级作用域变量声明 let x = 1; const y = 2; ES6
箭头函数 简化的函数语法 const add = (a,b) => a+b; ES6
模板字符串 多行字符串和字符串插值 `Hello ${name}` ES6
解构赋值 从数组或对象中提取值 const {a,b} = obj; ES6
默认参数 函数参数的默认值 function greet(name='游客'){} ES6
展开运算符 展开数组或对象 [...arr1, ...arr2] ES6
剩余参数 将多个参数收集为数组 function(...args){} ES6
Promise 异步编程解决方案 new Promise() ES6
基于类的面向对象编程 class MyClass {} ES6
模块 ES6模块系统 import/export ES6
Symbol 唯一的原始数据类型 const sym = Symbol(); ES6
Map/Set 新的数据结构 new Map(), new Set() ES6
async/await 异步编程语法糖 async function f() { await p; } ES2017
可选链 安全访问嵌套属性 obj?.prop?.subprop ES2020
空值合并 提供默认值的运算符 value ?? defaultValue ES2020
BigInt 大整数类型 123n ES2020
全局This 统一的全局对象 globalThis ES2020

ES6+特性示例

ES6+特性综合示例
// 解构赋值
const person = { name: '张三', age: 25, city: '北京' };
const { name, age, country = '中国' } = person;
console.log(name, age, country); // 张三 25 中国

// 数组解构
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;
console.log(first, second, rest); // 1 2 [3,4,5]

// 函数参数解构
function printPerson({ name, age = 18 }) {
    console.log(`${name} 今年 ${age} 岁`);
}
printPerson({ name: '李四' }); // 李四 今年 18 岁

// 展开运算符
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined); // [1,2,3,4,5,6]

// 对象展开
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const merged = { ...obj1, ...obj2, e: 5 };
console.log(merged); // {a:1,b:2,c:3,d:4,e:5}

// 箭头函数
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
console.log(doubled, evens); // [2,4,6,8,10] [2,4]

// this绑定示例
const counter = {
    count: 0,
    increment: function() {
        setInterval(() => {
            // 箭头函数继承外层this
            this.count++;
            console.log(this.count);
        }, 1000);
    }
};
// counter.increment();

// 类
class Person {
    // 类字段 (ES2022)
    #privateField = '私有字段';
    
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    // 实例方法
    greet() {
        return `你好,我是${this.name},今年${this.age}岁`;
    }
    
    // 静态方法
    static isAdult(age) {
        return age >= 18;
    }
    
    // 私有方法 (ES2022)
    #privateMethod() {
        return '这是私有方法';
    }
    
    // Getter
    get description() {
        return `${this.name} (${this.age}岁)`;
    }
    
    // Setter
    set updateAge(newAge) {
        if (newAge > 0) {
            this.age = newAge;
        }
    }
}

const john = new Person('约翰', 30);
console.log(john.greet()); // 你好,我是约翰,今年30岁
console.log(Person.isAdult(20)); // true
console.log(john.description); // 约翰 (30岁)
john.updateAge = 31;
console.log(john.age); // 31

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

const student = new Student('小明', 20, 'A');
console.log(student.greet()); // 你好,我是小明,今年20岁
console.log(student.study()); // 小明正在学习

// Promise
const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            Math.random() > 0.3 ? 
                resolve('数据获取成功') : 
                reject('数据获取失败');
        }, 1000);
    });
};

// async/await
async function getData() {
    try {
        const data = await fetchData();
        console.log(data);
        return data;
    } catch (error) {
        console.error('错误:', error);
        throw error;
    }
}

getData();

// 可选链和空值合并
const user = {
    profile: {
        name: '张三',
        address: {
            city: '北京'
        }
    }
};

console.log(user.profile?.name); // '张三'
console.log(user.profile?.age ?? '未知'); // '未知'
console.log(user.settings?.theme ?? 'default'); // 'default'

// BigInt
const bigNumber = 1234567890123456789012345678901234567890n;
console.log(bigNumber + 1n); // 1234567890123456789012345678901234567891n

// 全局This
console.log(globalThis === window); // 在浏览器中为true
console.log(globalThis === global); // 在Node.js中为true

// 动态导入
async function loadModule() {
    const module = await import('./utils.js');
    return module.default;
}

// 顶层await (ES2022)
// const data = await fetch('/api/data').then(r => r.json());

Promise与异步编程

Promise是JavaScript中处理异步操作的标准方式,async/await是基于Promise的语法糖,使异步代码更易读写。

Promise方法

方法 描述 语法 返回值 ES版本
Promise.resolve() 创建已解决的Promise Promise.resolve(value) Promise ES6
Promise.reject() 创建已拒绝的Promise Promise.reject(reason) Promise ES6
Promise.all() 等待所有Promise完成 Promise.all(iterable) Promise ES6
Promise.allSettled() 等待所有Promise完成(无论成功失败) Promise.allSettled(iterable) Promise ES2020
Promise.race() 等待第一个完成的Promise Promise.race(iterable) Promise ES6
Promise.any() 等待第一个成功的Promise Promise.any(iterable) Promise ES2021

Promise与异步示例

Promise和async/await示例
// 创建Promise
const fetchUserData = (userId) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId > 0) {
                resolve({ id: userId, name: '张三', age: 25 });
            } else {
                reject(new Error('用户ID无效'));
            }
        }, 1000);
    });
};

// 使用Promise
fetchUserData(1)
    .then(user => {
        console.log('用户数据:', user);
        return user.age;
    })
    .then(age => {
        console.log('用户年龄:', age);
    })
    .catch(error => {
        console.error('错误:', error.message);
    })
    .finally(() => {
        console.log('请求完成');
    });

// async/await
async function getUserInfo(userId) {
    try {
        console.log('开始获取用户信息...');
        const user = await fetchUserData(userId);
        console.log('用户信息:', user);
        return user;
    } catch (error) {
        console.error('获取用户信息失败:', error.message);
        throw error;
    } finally {
        console.log('用户信息获取过程结束');
    }
}

getUserInfo(1);

// Promise.all - 并行执行多个异步操作
async function fetchMultipleUsers() {
    try {
        const [user1, user2, user3] = await Promise.all([
            fetchUserData(1),
            fetchUserData(2),
            fetchUserData(3)
        ]);
        console.log('所有用户数据:', user1, user2, user3);
        return [user1, user2, user3];
    } catch (error) {
        console.error('获取用户数据失败:', error);
    }
}

// Promise.allSettled - 等待所有Promise完成
async function fetchUsersSettled() {
    const results = await Promise.allSettled([
        fetchUserData(1),
        fetchUserData(-1), // 这个会失败
        fetchUserData(3)
    ]);
    
    const successfulUsers = results
        .filter(result => result.status === 'fulfilled')
        .map(result => result.value);
    
    const errors = results
        .filter(result => result.status === 'rejected')
        .map(result => result.reason);
    
    console.log('成功获取的用户:', successfulUsers);
    console.log('错误:', errors);
}

// Promise.race - 第一个完成的结果
async function fetchWithTimeout() {
    const timeout = new Promise((_, reject) => {
        setTimeout(() => reject(new Error('请求超时')), 500);
    });
    
    try {
        const user = await Promise.race([
            fetchUserData(1),
            timeout
        ]);
        console.log('获取的用户:', user);
    } catch (error) {
        console.error('错误:', error.message);
    }
}

// Promise.any - 第一个成功的结果
async function fetchFirstSuccessful() {
    const promises = [
        fetchUserData(-1), // 失败
        fetchUserData(2),  // 成功
        fetchUserData(3)   // 成功
    ];
    
    try {
        const user = await Promise.any(promises);
        console.log('第一个成功的用户:', user);
    } catch (error) {
        console.error('所有请求都失败了:', error);
    }
}

// 实际应用:顺序执行异步操作
async function processUserData(userId) {
    try {
        // 1. 获取用户数据
        const user = await fetchUserData(userId);
        
        // 2. 获取用户订单
        const orders = await fetchUserOrders(user.id);
        
        // 3. 获取用户地址
        const addresses = await fetchUserAddresses(user.id);
        
        return {
            ...user,
            orders,
            addresses
        };
    } catch (error) {
        console.error('处理用户数据失败:', error);
        throw error;
    }
}

// 模拟其他API函数
function fetchUserOrders(userId) {
    return Promise.resolve([
        { id: 1, product: '手机', price: 2999 },
        { id: 2, product: '耳机', price: 299 }
    ]);
}

function fetchUserAddresses(userId) {
    return Promise.resolve([
        { type: '家', address: '北京市朝阳区' },
        { type: '公司', address: '北京市海淀区' }
    ]);
}

// 使用示例
processUserData(1).then(userData => {
    console.log('完整的用户数据:', userData);
});

// 错误处理最佳实践
async function robustAsyncFunction() {
    try {
        const result = await someAsyncOperation();
        return result;
    } catch (error) {
        // 记录错误
        console.error('异步操作失败:', error);
        
        // 根据错误类型处理
        if (error.name === 'NetworkError') {
            // 重试逻辑
            return retryOperation();
        } else if (error.name === 'ValidationError') {
            // 返回默认值
            return getDefaultValue();
        } else {
            // 重新抛出未知错误
            throw error;
        }
    }
}

浏览器兼容性参考

了解不同JavaScript特性在主流浏览器中的支持情况。

特性 Chrome Firefox Safari Edge IE
ES6 (let/const) 49+ 44+ 10+ 12+ 11 (部分)
箭头函数 45+ 22+ 10+ 12+ -
Promise 32+ 29+ 8+ 12+ -
async/await 55+ 52+ 10.1+ 15+ -
模块 (import/export) 61+ 60+ 10.1+ 16+ -
可选链 (?.) 80+ 74+ 13.1+ 80+ -
空值合并 (??) 80+ 72+ 13.1+ 80+ -
Fetch API 42+ 39+ 10.1+ 14+ -
兼容性提示:
  • 对于需要支持旧版浏览器的项目,建议使用Babel等转译工具将现代JavaScript代码转换为兼容性更好的ES5代码。
  • 使用polyfill库(如core-js)为旧浏览器提供现代JavaScript特性的支持。
  • 利用特性检测(Feature Detection)而不是浏览器检测来编写兼容性代码。
  • 考虑使用TypeScript,它可以编译为兼容性更好的JavaScript版本。

JavaScript最佳实践

代码质量

  • 使用严格模式 - 在文件或函数开头添加 'use strict'
  • 避免全局变量 - 使用模块化或IIFE封装代码
  • 使用const和let - 优先使用const,需要重新赋值时使用let
  • 使用===和!== - 避免类型转换带来的意外行为
  • 使用模板字符串 - 替代字符串拼接,提高可读性

性能优化

  • 减少DOM操作 - 批量更新DOM或使用文档片段
  • 事件委托 - 利用事件冒泡减少事件监听器数量
  • 防抖和节流 - 优化频繁触发的事件处理函数
  • 避免内存泄漏 - 及时清理事件监听器和定时器
  • 使用Web Workers - 将计算密集型任务移到后台线程

安全实践

  • 验证用户输入 - 始终在服务器端和客户端验证数据
  • 避免eval() - 使用JSON.parse()或其他安全替代方案
  • 内容安全策略 - 使用CSP头防止XSS攻击
  • HTTPS - 在生产环境中始终使用HTTPS
  • 清理HTML - 使用textContent而不是innerHTML插入文本

更多资源

要进一步深入学习JavaScript,可以参考以下资源: