Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • web
  • web concept
  • javascript

    • javascript 入门指南
      • 学习目标
      • 1. JavaScript 基础语法
        • 1.1 环境搭建
        • 1.2 基本概念
        • 1.3 数据类型
        • 原始类型
        • 引用类型
        • 1.4 变量和赋值
        • 1.5 运算符
      • 2. 控制流程
        • 2.1 条件语句
        • 2.2 循环语句
        • 2.3 异常处理
      • 3. 函数和模块
        • 3.1 函数定义
        • 3.2 函数高级特性
        • 3.3 模块系统
      • 4. 面向对象编程
        • 4.1 类和对象
        • 4.2 继承和多态
        • 4.3 特殊方法
      • 5. 数据处理基础
        • 5.1 数组操作
        • 5.2 对象操作
        • 5.3 字符串处理
      • 6. 异步编程
        • 6.1 Promise
        • 6.2 async/await
      • 7. 现代 JavaScript 特性
        • 7.1 ES6+ 特性
        • 7.2 高级语法
      • 8. 函数式编程
        • 8.1 高阶函数
        • 8.2 不可变性
      • 9. 错误处理和调试
        • 9.1 错误处理策略
        • 9.2 调试技巧
      • 10. 最佳实践
        • 10.1 代码规范
        • 10.2 性能优化
      • 11. 实用技巧和常用函数
        • 11.1 常用工具函数
        • 11.2 数组操作技巧
        • 11.3 对象操作技巧
      • 12. 学习资源
        • 官方文档
        • 在线教程
        • 实践项目
        • 社区资源
      • 学习路径建议
        • 初级阶段(1-2个月)
        • 中级阶段(2-3个月)
        • 高级阶段(3-6个月)
        • 专家阶段(6个月以上)
      • 常见问题
        • Q: 如何选择 JavaScript 版本?
        • Q: 学习 JavaScript 需要什么基础?
        • Q: 如何提高编程效率?
        • Q: 学完基础后应该学什么?
      • 总结
      • 附录:常用 API 参考
        • Object 方法
        • Array 方法
        • 1. 数组增删操作
        • 2. 数组切片和修改
        • 3. 函数式编程方法
        • 4. 查找方法
        • 5. 排序和反转
        • 6. 实用组合示例
        • 7. 性能优化技巧
    • JavaScript 实用代码片段
  • css

  • vue

  • react

  • nextjs

  • module

  • web faq
  • web3

  • more

  • 《web》
  • javascript
Jacky
2024-08-06
目录

javascript 入门指南

Reference (opens new window)

# 学习目标

本大纲旨在为 JavaScript 初学者提供系统性的学习路径,从基础语法到现代开发,逐步掌握 JavaScript 编程技能。

# 1. JavaScript 基础语法

# 1.1 环境搭建

  • Node.js 安装和配置
  • 浏览器开发者工具使用
  • 代码编辑器选择和配置(VS Code, WebStorm)
  • 包管理工具(npm, yarn)
  • 模块打包工具(Webpack, Vite)

# 1.2 基本概念

  • JavaScript 简介和特点
  • 第一个 JavaScript 程序
  • 代码注释和文档字符串
  • 代码规范和 ESLint

# 1.3 数据类型

# 原始类型

// 数字
let integer = 42;
let float = 3.14159;
let infinity = Infinity;
let notANumber = NaN;

// 字符串
let singleQuote = 'Hello';
let doubleQuote = "World";
let template = `Hello ${name}`;

// 布尔值
let isTrue = true;
let isFalse = false;

// undefined 和 null
let undefinedVar = undefined;
let nullVar = null;

// Symbol(ES6)
let symbol = Symbol('description');

// BigInt(ES2020)
let bigInt = 9007199254740991n;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 引用类型

// 对象
let person = {
    name: 'Alice',
    age: 25,
    greet() {
        return `Hello, I'm ${this.name}`;
    }
};

// 数组
let numbers = [1, 2, 3, 4, 5];
let mixed = [1, 'hello', true, { key: 'value' }];

// 函数
function greet(name) {
    return `Hello, ${name}!`;
}

// 日期
let now = new Date();
let specificDate = new Date('2024-01-01');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 1.4 变量和赋值

// 变量声明
var oldWay = 'legacy';           // 函数作用域
let modernWay = 'ES6';           // 块级作用域
const constant = 'immutable';    // 常量

// 解构赋值
let [a, b, c] = [1, 2, 3];
let { name, age } = { name: 'Alice', age: 25 };

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

let obj1 = { x: 1, y: 2 };
let obj2 = { ...obj1, z: 3 };    // { x: 1, y: 2, z: 3 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 1.5 运算符

// 算术运算符
let sum = 10 + 5;        // 加法
let diff = 10 - 5;       // 减法
let product = 10 * 5;    // 乘法
let quotient = 10 / 5;   // 除法
let remainder = 10 % 3;  // 取余
let power = 10 ** 2;     // 幂运算

// 比较运算符
let equal = 5 == '5';        // 宽松相等
let strictEqual = 5 === '5'; // 严格相等
let notEqual = 5 != '6';     // 宽松不等
let strictNotEqual = 5 !== '5'; // 严格不等

// 逻辑运算符
let and = true && false;      // 逻辑与
let or = true || false;       // 逻辑或
let not = !true;              // 逻辑非

// 空值合并运算符(ES2020)
let result = null ?? 'default';   // 只有 null 或 undefined 时使用默认值

// 可选链操作符(ES2020)
let value = obj?.prop?.subProp;   // 安全访问嵌套属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 2. 控制流程

# 2.1 条件语句

// if 语句
if (condition) {
    // 执行代码
}

// if-else 语句
if (condition) {
    // 条件为真时执行
} else {
    // 条件为假时执行
}

// if-else if-else 语句
if (condition1) {
    // 条件1为真时执行
} else if (condition2) {
    // 条件2为真时执行
} else {
    // 所有条件都为假时执行
}

// 三元运算符
let result = condition ? valueIfTrue : valueIfFalse;

// switch 语句
switch (value) {
    case 1:
        console.log('One');
        break;
    case 2:
        console.log('Two');
        break;
    default:
        console.log('Default');
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 2.2 循环语句

// for 循环
for (let i = 0; i < 10; i++) {
    console.log(i);
}

// for...of 循环(ES6)
for (let item of array) {
    console.log(item);
}

// for...in 循环
for (let key in object) {
    console.log(key, object[key]);
}

// while 循环
while (condition) {
    // 执行代码
}

// do...while 循环
do {
    // 执行代码
} while (condition);

// 循环控制
for (let i = 0; i < 10; i++) {
    if (i === 5) {
        break;      // 跳出循环
    }
    if (i === 2) {
        continue;   // 跳过当前迭代
    }
    console.log(i);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 2.3 异常处理

try {
    // 可能出错的代码
    throw new Error('Something went wrong');
} catch (error) {
    // 处理异常
    console.error('Error:', error.message);
} finally {
    // 无论是否异常都执行
    console.log('Cleanup');
}

// 自定义错误
class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CustomError';
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 3. 函数和模块

# 3.1 函数定义

// 函数声明
function greet(name) {
    return `Hello, ${name}!`;
}

// 函数表达式
const greet = function(name) {
    return `Hello, ${name}!`;
};

// 箭头函数(ES6)
const greet = (name) => `Hello, ${name}!`;

// 默认参数
function greet(name = 'World') {
    return `Hello, ${name}!`;
}

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}

// 解构参数
function processUser({ name, age, email }) {
    console.log(`${name} is ${age} years old`);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 3.2 函数高级特性

// 高阶函数
function withLogging(fn) {
    return function(...args) {
        console.log('Calling function with:', args);
        const result = fn(...args);
        console.log('Function returned:', result);
        return result;
    };
}

// 闭包
function createCounter() {
    let count = 0;
    return function() {
        return ++count;
    };
}

// 立即执行函数表达式(IIFE)
(function() {
    console.log('IIFE executed');
})();

// 生成器函数(ES6)
function* fibonacci() {
    let [a, b] = [0, 1];
    while (true) {
        yield a;
        [a, b] = [b, a + b];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 3.3 模块系统

// ES6 模块
// math.js
export const add = (a, b) => a + b;
export const subtract = (a, b) => a - b;
export default class Calculator {
    add(a, b) { return a + b; }
}

// main.js
import Calculator, { add, subtract } from './math.js';
import * as math from './math.js';

// CommonJS(Node.js)
// math.js
module.exports = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b
};

// main.js
const math = require('./math.js');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 4. 面向对象编程

# 4.1 类和对象

// 类定义(ES6)
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    greet() {
        return `Hello, I'm ${this.name}`;
    }
    
    get info() {
        return `${this.name} is ${this.age} years old`;
    }
    
    set info(value) {
        [this.name, this.age] = value.split(' ');
    }
}

// 创建实例
const person = new Person('Alice', 25);
console.log(person.greet());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 4.2 继承和多态

class Animal {
    constructor(name) {
        this.name = name;
    }
    
    speak() {
        return 'Some sound';
    }
}

class Dog extends Animal {
    speak() {
        return 'Woof!';
    }
}

class Cat extends Animal {
    speak() {
        return 'Meow!';
    }
}

// 多态
const animals = [new Dog('Rex'), new Cat('Whiskers')];
animals.forEach(animal => console.log(animal.speak()));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 4.3 特殊方法

class Vector {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    
    toString() {
        return `Vector(${this.x}, ${this.y})`;
    }
    
    valueOf() {
        return Math.sqrt(this.x ** 2 + this.y ** 2);
    }
    
    [Symbol.iterator]() {
        return [this.x, this.y][Symbol.iterator]();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 5. 数据处理基础

# 5.1 数组操作

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

// 添加/删除元素
numbers.push(6);           // 末尾添加
numbers.pop();             // 末尾删除
numbers.unshift(0);        // 开头添加
numbers.shift();           // 开头删除

// clear
numbers.length = 0;                 // Method 1: Set length to 0 (most efficient)
numbers = [];                       // Method 2: Assign empty array
numbers.splice(0, numbers.length);  // Method 3: Use splice to remove all elements
while (numbers.length > 0) {        // Method 4: Use pop() in a loop (less efficient)
    numbers.pop();
}

// remove: 找到元素 key 在数组中的索引位置, 从该索引位置开始,删除 1 个元素
numbers.splice(numbers.indexOf(key), 1)

// 遍历方法
numbers.forEach(num => console.log(num));
const doubled = numbers.map(num => num * 2);
const evens = numbers.filter(num => num % 2 === 0);
const sum = numbers.reduce((acc, num) => acc + num, 0);

// 查找方法
const found = numbers.find(num => num > 3);
const index = numbers.findIndex(num => num > 3);
const includes = numbers.includes(3);

// 排序和反转
numbers.sort((a, b) => a - b);
numbers.reverse();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 5.2 对象操作

// 对象方法
const person = { name: 'Alice', age: 25 };

// 获取键值
Object.keys(person);       // ['name', 'age']
Object.values(person);     // ['Alice', 25]
Object.entries(person);    // [['name', 'Alice'], ['age', 25]]

// 合并对象
const newPerson = Object.assign({}, person, { city: 'New York' });
const merged = { ...person, city: 'New York' };

// 冻结对象
Object.freeze(person);     // 不可修改
Object.seal(person);       // 可修改属性值,但不能添加/删除属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 5.3 字符串处理

// 字符串方法
const text = '  Hello, World!  ';

// 基本操作
text.trim();               // 去除首尾空格
text.toLowerCase();        // 转小写
text.toUpperCase();        // 转大写
text.replace('World', 'JavaScript');  // 替换

// 分割和连接
text.split(', ');          // 分割字符串
['Hello', 'World'].join(' ');  // 连接数组

// 模板字符串(ES6)
const name = 'Alice';
const greeting = `Hello, ${name}!`;
const multiline = `
    This is a
    multiline string
`;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 6. 异步编程

# 6.1 Promise

// 创建 Promise
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        const random = Math.random();
        if (random > 0.5) {
            resolve('Success!');
        } else {
            reject('Failed!');
        }
    }, 1000);
});

// 使用 Promise
myPromise
    .then(result => console.log(result))
    .catch(error => console.error(error))
    .finally(() => console.log('Done'));

// Promise.all
const promises = [
    fetch('/api/users'),
    fetch('/api/posts'),
    fetch('/api/comments')
];

Promise.all(promises)
    .then(responses => Promise.all(responses.map(r => r.json())))
    .then(data => console.log(data));

// Promise.race
Promise.race([
    fetch('/api/data'),
    new Promise((_, reject) => setTimeout(() => reject('Timeout'), 5000))
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 6.2 async/await

// async 函数
async function fetchUser(id) {
    try {
        const response = await fetch(`/api/users/${id}`);
        if (!response.ok) {
            throw new Error('User not found');
        }
        return await response.json();
    } catch (error) {
        console.error('Error:', error);
        throw error;
    }
}

// 并行执行
async function fetchMultipleUsers(ids) {
    const promises = ids.map(id => fetchUser(id));
    return await Promise.all(promises);
}

// 错误处理
async function handleErrors() {
    try {
        const result = await riskyOperation();
        return result;
    } catch (error) {
        console.error('Operation failed:', error);
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 7. 现代 JavaScript 特性

# 7.1 ES6+ 特性

// 解构赋值
const [a, b, ...rest] = [1, 2, 3, 4, 5];
const { name, age, ...otherProps } = person;

// 默认参数
function greet(name = 'World', greeting = 'Hello') {
    return `${greeting}, ${name}!`;
}

// 剩余参数
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}

// 展开运算符
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
const obj1 = { x: 1, y: 2 };
const obj2 = { ...obj1, z: 3 };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 7.2 高级语法

// 可选链操作符(ES2020)
const value = obj?.prop?.subProp?.method?.();

// 空值合并操作符(ES2020)
const result = value ?? defaultValue;

// 逻辑赋值操作符(ES2021)
let x = 1;
x ||= 2;    // x = x || 2
x &&= 3;    // x = x && 3
x ??= 4;    // x = x ?? 4

// 私有类字段(ES2022)
class Counter {
    #count = 0;
    
    increment() {
        this.#count++;
    }
    
    getCount() {
        return this.#count;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 8. 函数式编程

# 8.1 高阶函数

// map
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);

// filter
const evens = numbers.filter(x => x % 2 === 0);

// reduce
const sum = numbers.reduce((acc, x) => acc + x, 0);

// 组合函数
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);
const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const addOne = x => x + 1;
const double = x => x * 2;
const square = x => x ** 2;

const transform = compose(square, double, addOne);
console.log(transform(3)); // ((3 + 1) * 2) ^ 2 = 64
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 8.2 不可变性

// 不可变数组操作
const original = [1, 2, 3];
const updated = [...original, 4];           // 添加元素
const filtered = original.filter(x => x !== 2);  // 删除元素
const mapped = original.map(x => x * 2);    // 修改元素

// 不可变对象操作
const original = { name: 'Alice', age: 25 };
const updated = { ...original, age: 26 };   // 修改属性
const { age, ...withoutAge } = original;    // 删除属性
1
2
3
4
5
6
7
8
9
10

# 9. 错误处理和调试

# 9.1 错误处理策略

// 自定义错误类
class ValidationError extends Error {
    constructor(message, field) {
        super(message);
        this.name = 'ValidationError';
        this.field = field;
    }
}

// 错误边界
function withErrorBoundary(fn) {
    return function(...args) {
        try {
            return fn.apply(this, args);
        } catch (error) {
            console.error('Function failed:', error);
            // 可以发送错误到监控服务
            return null;
        }
    };
}

// 异步错误处理
async function handleAsyncErrors() {
    try {
        const result = await riskyAsyncOperation();
        return result;
    } catch (error) {
        if (error.name === 'NetworkError') {
            // 处理网络错误
            return retryOperation();
        } else if (error.name === 'ValidationError') {
            // 处理验证错误
            return showValidationMessage(error.message);
        } else {
            // 处理其他错误
            throw error;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 9.2 调试技巧

// 调试工具
console.log('Debug info:', variable);
console.table(arrayOfObjects);
console.group('Group name');
console.groupEnd();
console.time('Operation');
console.timeEnd('Operation');

// 条件断点
if (condition) {
    debugger; // 只在条件满足时暂停
}

// 性能监控
const startTime = performance.now();
// ... 执行代码
const endTime = performance.now();
console.log(`Execution time: ${endTime - startTime}ms`);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 10. 最佳实践

# 10.1 代码规范

// ESLint 配置示例
// .eslintrc.js
module.exports = {
    extends: ['eslint:recommended'],
    rules: {
        'no-unused-vars': 'error',
        'no-console': 'warn',
        'prefer-const': 'error',
        'no-var': 'error'
    }
};

// 代码风格
// 使用 const 和 let,避免 var
const PI = 3.14159;
let counter = 0;

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

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

// 使用解构赋值
const { name, age } = user;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 10.2 性能优化

// 避免重复计算
const expensive = (() => {
    const result = heavyComputation();
    return () => result;
})();

// 防抖和节流
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

// 内存管理
class Cache {
    constructor(maxSize = 100) {
        this.cache = new Map();
        this.maxSize = maxSize;
    }
    
    set(key, value) {
        if (this.cache.size >= this.maxSize) {
            const firstKey = this.cache.keys().next().value;
            this.cache.delete(firstKey);
        }
        this.cache.set(key, value);
    }
    
    get(key) {
        return this.cache.get(key);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 11. 实用技巧和常用函数

# 11.1 常用工具函数

// 类型检查
const isString = value => typeof value === 'string';
const isNumber = value => typeof value === 'number' && !isNaN(value);
const isArray = value => Array.isArray(value);
const isObject = value => value !== null && typeof value === 'object';
const isFunction = value => typeof value === 'function';

// 深拷贝
function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (obj instanceof Date) return new Date(obj.getTime());
    if (obj instanceof Array) return obj.map(item => deepClone(item));
    if (typeof obj === 'object') {
        const clonedObj = {};
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                clonedObj[key] = deepClone(obj[key]);
            }
        }
        return clonedObj;
    }
}

// 防抖函数
function debounce(func, wait, immediate = false) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            timeout = null;
            if (!immediate) func.apply(this, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(this, args);
    };
}

// 节流函数
function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# 11.2 数组操作技巧

// 数组去重
const unique = [...new Set(array)];
const uniqueByKey = (array, key) => {
    const seen = new Set();
    return array.filter(item => {
        const value = item[key];
        if (seen.has(value)) {
            return false;
        }
        seen.add(value);
        return true;
    });
};

// 数组分组
function groupBy(array, key) {
    return array.reduce((groups, item) => {
        const group = item[key];
        groups[group] = groups[group] || [];
        groups[group].push(item);
        return groups;
    }, {});
}

// 数组分块
function chunk(array, size) {
    const chunks = [];
    for (let i = 0; i < array.length; i += size) {
        chunks.push(array.slice(i, i + size));
    }
    return chunks;
}

// 数组扁平化
function flatten(array, depth = Infinity) {
    return depth > 0
        ? array.reduce((acc, val) => 
            acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val), [])
        : array.slice();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 11.3 对象操作技巧

// 对象扁平化
function flattenObject(obj, prefix = '') {
    return Object.keys(obj).reduce((acc, key) => {
        const pre = prefix.length ? prefix + '.' : '';
        if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
            Object.assign(acc, flattenObject(obj[key], pre + key));
        } else {
            acc[pre + key] = obj[key];
        }
        return acc;
    }, {});
}

// 对象深合并
function deepMerge(target, source) {
    const result = { ...target };
    for (const key in source) {
        if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
            result[key] = deepMerge(result[key] || {}, source[key]);
        } else {
            result[key] = source[key];
        }
    }
    return result;
}

// 对象属性选择
function pick(obj, keys) {
    return keys.reduce((result, key) => {
        if (key in obj) {
            result[key] = obj[key];
        }
        return result;
    }, {});
}

function omit(obj, keys) {
    return Object.keys(obj)
        .filter(key => !keys.includes(key))
        .reduce((result, key) => {
            result[key] = obj[key];
            return result;
        }, {});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 12. 学习资源

# 官方文档

  • MDN Web Docs (opens new window)
  • ECMAScript 规范 (opens new window)
  • Node.js 文档 (opens new window)

# 在线教程

  • JavaScript.info (opens new window)
  • Eloquent JavaScript (opens new window)
  • You Don't Know JS (opens new window)

# 实践项目

  • JavaScript 30 (opens new window)
  • Frontend Mentor (opens new window)
  • Codewars (opens new window)

# 社区资源

  • Stack Overflow (opens new window)
  • Reddit r/javascript (opens new window)
  • JavaScript Weekly (opens new window)

# 学习路径建议

# 初级阶段(1-2个月)

  1. 掌握 JavaScript 基础语法
  2. 熟悉数据类型和变量
  3. 学会函数定义和调用
  4. 理解作用域和闭包
  5. 完成基础项目练习

# 中级阶段(2-3个月)

  1. 深入学习面向对象编程
  2. 掌握异步编程(Promise, async/await)
  3. 学习 ES6+ 新特性
  4. 理解函数式编程概念
  5. 开始使用现代工具链

# 高级阶段(3-6个月)

  1. 学习设计模式
  2. 掌握性能优化技巧
  3. 深入理解 JavaScript 引擎
  4. 学习测试和调试
  5. 完成综合项目

# 专家阶段(6个月以上)

  1. 深入研究特定领域(前端框架、Node.js等)
  2. 参与开源项目
  3. 学习高级概念(微前端、WebAssembly等)
  4. 持续学习和实践

# 常见问题

# Q: 如何选择 JavaScript 版本?

A: 现代开发推荐使用 ES6+ 特性,通过 Babel 等工具进行转译以支持旧浏览器。

# Q: 学习 JavaScript 需要什么基础?

A: 基本的 HTML 和 CSS 知识,以及计算机操作能力即可。

# Q: 如何提高编程效率?

A: 多练习、使用现代开发工具、阅读优秀代码、参与开源项目。

# Q: 学完基础后应该学什么?

A: 根据方向选择:前端框架(React、Vue、Angular)、Node.js 后端开发、移动端开发等。

# 总结

JavaScript 是一门强大而灵活的编程语言,是现代 Web 开发的核心技术。通过系统性的学习和持续的实践,您可以掌握 JavaScript 编程技能,并在各个领域发挥其优势。

记住:编程是一门实践的艺术,多写代码、多调试、多思考,才能真正掌握 JavaScript 编程。


# 附录:常用 API 参考

# Object 方法

  • Object.assign(target, source): 复制所有可枚举属性到目标对象
  • Object.keys(obj): 返回对象自身可枚举属性的键名数组
  • Object.values(obj): 返回对象自身可枚举属性的值数组
  • Object.entries(obj): 返回对象自身可枚举属性的键值对数组
  • Object.freeze(obj): 冻结对象,使其不可修改
  • Object.seal(obj): 密封对象,可修改属性值但不能添加/删除属性

# Array 方法

# 1. 数组增删操作

// push() - 在数组末尾添加一个或多个元素
const fruits = ['apple', 'banana'];
fruits.push('orange');           // 返回新长度: 3
fruits.push('grape', 'mango');   // 可以添加多个元素
console.log(fruits);             // ['apple', 'banana', 'orange', 'grape', 'mango']

// pop() - 删除并返回数组的最后一个元素
const lastFruit = fruits.pop();  // 返回: 'mango'
console.log(fruits);             // ['apple', 'banana', 'orange', 'grape']

// shift() - 删除并返回数组的第一个元素
const firstFruit = fruits.shift(); // 返回: 'apple'
console.log(fruits);               // ['banana', 'orange', 'grape']

// unshift() - 在数组开头添加一个或多个元素
fruits.unshift('kiwi');          // 返回新长度: 4
fruits.unshift('pear', 'plum');  // 可以添加多个元素
console.log(fruits);             // ['pear', 'plum', 'kiwi', 'banana', 'orange', 'grape']

// 性能对比:shift/unshift 比 push/pop 慢,因为需要移动所有元素
const largeArray = new Array(10000).fill(0);
console.time('shift');
largeArray.shift();              // 慢 - O(n)
console.timeEnd('shift');

console.time('pop');
largeArray.pop();                // 快 - O(1)
console.timeEnd('pop');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 2. 数组切片和修改

// slice(startIndex, endIndex) - 提取数组的一部分,不修改原数组
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const firstThree = numbers.slice(0, 3);     // [1, 2, 3]
const lastThree = numbers.slice(-3);        // [8, 9, 10]
const middle = numbers.slice(3, 7);         // [4, 5, 6, 7]
const copy = numbers.slice();               // 浅拷贝整个数组

console.log(numbers);                       // 原数组不变: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

// splice(startIndex, deleteCount, ...items) - 修改数组,删除/插入元素
const colors = ['red', 'green', 'blue', 'yellow', 'purple'];

// 删除元素
const removed = colors.splice(1, 2);        // 从索引1开始删除2个元素
console.log(removed);                       // ['green', 'blue']
console.log(colors);                        // ['red', 'yellow', 'purple']

// 插入元素
colors.splice(1, 0, 'orange', 'pink');      // 在索引1处插入元素,不删除
console.log(colors);                        // ['red', 'orange', 'pink', 'yellow', 'purple']

// 替换元素
colors.splice(2, 1, 'cyan');                // 替换索引2处的元素
console.log(colors);                        // ['red', 'orange', 'cyan', 'yellow', 'purple']

// 删除末尾元素
colors.splice(-1, 1);                       // 删除最后一个元素
console.log(colors);                        // ['red', 'orange', 'cyan', 'yellow']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 3. 函数式编程方法

// map() - 对数组中的每个元素执行函数,返回新数组
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map(x => x * 2);           // [2, 4, 6, 8, 10]
const squared = numbers.map(x => x ** 2);          // [1, 4, 9, 16, 25]
const formatted = numbers.map(x => `Number: ${x}`); // ['Number: 1', 'Number: 2', ...]

// 对象数组的 map 操作
const users = [
    { id: 1, name: 'Alice', age: 25 },
    { id: 2, name: 'Bob', age: 30 },
    { id: 3, name: 'Charlie', age: 35 }
];

const names = users.map(user => user.name);        // ['Alice', 'Bob', 'Charlie']
const userInfo = users.map(user => ({
    id: user.id,
    info: `${user.name} (${user.age})`
}));

// filter() - 过滤数组元素,返回满足条件的元素
const scores = [85, 92, 78, 96, 88, 75, 90];

const highScores = scores.filter(score => score >= 90);     // [92, 96, 90]
const evenScores = scores.filter(score => score % 2 === 0); // [92, 78, 96, 88, 90]

// 对象数组的 filter 操作
const activeUsers = users.filter(user => user.age < 35);    // 只保留年龄小于35的用户

// reduce() - 将数组归并为单个值
const sum = numbers.reduce((acc, curr) => acc + curr, 0);   // 15
const product = numbers.reduce((acc, curr) => acc * curr, 1); // 120

// 复杂 reduce 示例
const orders = [
    { product: 'apple', price: 2.5, quantity: 3 },
    { product: 'banana', price: 1.5, quantity: 2 },
    { product: 'orange', price: 3.0, quantity: 1 }
];

const totalValue = orders.reduce((total, order) => {
    return total + (order.price * order.quantity);
}, 0); // 11.5

// 分组统计
const words = ['apple', 'banana', 'apple', 'cherry', 'banana', 'apple'];
const wordCount = words.reduce((count, word) => {
    count[word] = (count[word] || 0) + 1;
    return count;
}, {}); // { apple: 3, banana: 2, cherry: 1 }

// 链式调用
const result = numbers
    .filter(x => x % 2 === 0)    // [2, 4]
    .map(x => x * 2)             // [4, 8]
    .reduce((sum, x) => sum + x, 0); // 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 4. 查找方法

// find() - 返回第一个满足条件的元素
const users = [
    { id: 1, name: 'Alice', age: 25, active: true },
    { id: 2, name: 'Bob', age: 30, active: false },
    { id: 3, name: 'Charlie', age: 35, active: true },
    { id: 4, name: 'David', age: 28, active: true }
];

const firstActive = users.find(user => user.active);        // { id: 1, name: 'Alice', ... }
const youngUser = users.find(user => user.age < 30);       // { id: 1, name: 'Alice', ... }
const notFound = users.find(user => user.age > 50);        // undefined

// findIndex() - 返回第一个满足条件的元素索引
const activeIndex = users.findIndex(user => user.active);  // 0
const oldUserIndex = users.findIndex(user => user.age > 40); // -1 (未找到)

// includes() - 检查数组是否包含指定元素
const fruits = ['apple', 'banana', 'orange'];
console.log(fruits.includes('banana'));     // true
console.log(fruits.includes('grape'));      // false

// 对象数组的 includes 检查
const hasAlice = users.some(user => user.name === 'Alice'); // true
const allActive = users.every(user => user.active);         // false

// 高级查找示例
const searchUsers = (query) => {
    return users.filter(user => 
        user.name.toLowerCase().includes(query.toLowerCase()) ||
        user.id.toString().includes(query)
    );
};

console.log(searchUsers('al')); // [{ id: 1, name: 'Alice', ... }]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 5. 排序和反转

// sort() - 排序数组(默认按字符串排序)
const fruits = ['banana', 'apple', 'cherry', 'date'];
fruits.sort(); // ['apple', 'banana', 'cherry', 'date']

// 数字排序
const numbers = [10, 5, 8, 1, 9, 3];
numbers.sort(); // [1, 10, 3, 5, 8, 9] - 字符串排序!

// 正确的数字排序
numbers.sort((a, b) => a - b);  // 升序: [1, 3, 5, 8, 9, 10]
numbers.sort((a, b) => b - a);  // 降序: [10, 9, 8, 5, 3, 1]

// 对象数组排序
const students = [
    { name: 'Alice', grade: 85 },
    { name: 'Bob', grade: 92 },
    { name: 'Charlie', grade: 78 },
    { name: 'David', grade: 96 }
];

// 按成绩排序
students.sort((a, b) => b.grade - a.grade); // 按成绩降序

// 按名字排序
students.sort((a, b) => a.name.localeCompare(b.name));

// 多条件排序
const employees = [
    { name: 'Alice', department: 'HR', salary: 50000 },
    { name: 'Bob', department: 'IT', salary: 60000 },
    { name: 'Charlie', department: 'HR', salary: 55000 },
    { name: 'David', department: 'IT', salary: 65000 }
];

// 先按部门,再按薪资排序
employees.sort((a, b) => {
    if (a.department !== b.department) {
        return a.department.localeCompare(b.department);
    }
    return b.salary - a.salary;
});

// reverse() - 反转数组
const letters = ['a', 'b', 'c', 'd'];
letters.reverse(); // ['d', 'c', 'b', 'a']

// 创建反转副本(不修改原数组)
const reversed = [...letters].reverse();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 6. 实用组合示例

// 数组去重
const duplicates = [1, 2, 2, 3, 4, 4, 5];
const unique = [...new Set(duplicates)]; // [1, 2, 3, 4, 5]

// 对象数组去重
const users = [
    { id: 1, name: 'Alice' },
    { id: 2, name: 'Bob' },
    { id: 1, name: 'Alice' }, // 重复
    { id: 3, name: 'Charlie' }
];

const uniqueUsers = users.filter((user, index, self) => 
    index === self.findIndex(u => u.id === user.id)
);

// 数组分块
const chunk = (array, size) => {
    const chunks = [];
    for (let i = 0; i < array.length; i += size) {
        chunks.push(array.slice(i, i + size));
    }
    return chunks;
};

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(chunk(numbers, 3)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

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

// 数组交集、并集、差集
const set1 = [1, 2, 3, 4, 5];
const set2 = [4, 5, 6, 7, 8];

const intersection = set1.filter(x => set2.includes(x)); // [4, 5]
const union = [...new Set([...set1, ...set2])]; // [1, 2, 3, 4, 5, 6, 7, 8]
const difference = set1.filter(x => !set2.includes(x)); // [1, 2, 3]

// 数组统计
const grades = [85, 92, 78, 96, 88, 75, 90];

const stats = {
    count: grades.length,
    sum: grades.reduce((a, b) => a + b, 0),
    average: grades.reduce((a, b) => a + b, 0) / grades.length,
    min: Math.min(...grades),
    max: Math.max(...grades),
    range: Math.max(...grades) - Math.min(...grades)
};

// 数组分组
const groupBy = (array, key) => {
    return array.reduce((groups, item) => {
        const group = item[key];
        groups[group] = groups[group] || [];
        groups[group].push(item);
        return groups;
    }, {});
};

const products = [
    { name: 'Apple', category: 'Fruit', price: 2.5 },
    { name: 'Banana', category: 'Fruit', price: 1.5 },
    { name: 'Carrot', category: 'Vegetable', price: 1.0 },
    { name: 'Broccoli', category: 'Vegetable', price: 2.0 }
];

const grouped = groupBy(products, 'category');
// {
//   Fruit: [{ name: 'Apple', ... }, { name: 'Banana', ... }],
//   Vegetable: [{ name: 'Carrot', ... }, { name: 'Broccoli', ... }]
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

# 7. 性能优化技巧

// 避免在循环中修改数组长度
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 错误方式 - 可能导致无限循环
for (let i = 0; i < numbers.length; i++) {
    if (numbers[i] % 2 === 0) {
        numbers.splice(i, 1); // 修改数组长度
        i--; // 需要调整索引
    }
}

// 正确方式 - 从后往前遍历
for (let i = numbers.length - 1; i >= 0; i--) {
    if (numbers[i] % 2 === 0) {
        numbers.splice(i, 1);
    }
}

// 更好的方式 - 使用 filter
const oddNumbers = numbers.filter(n => n % 2 !== 0);

// 大数组操作优化
const largeArray = new Array(100000).fill(0).map((_, i) => i);

// 使用 for...of 替代 forEach(性能更好)
console.time('forEach');
largeArray.forEach(x => x * 2);
console.timeEnd('forEach');

console.time('for...of');
for (const x of largeArray) {
    x * 2;
}
console.timeEnd('for...of');

// 使用 Set 进行快速查找
const searchArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const searchSet = new Set(searchArray);

console.time('array includes');
searchArray.includes(5);
console.timeEnd('array includes');

console.time('set has');
searchSet.has(5);
console.timeEnd('set has');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#JavaScript#tutorial
上次更新: 2025/10/10, 14:12:02
web concept
JavaScript 实用代码片段

← web concept JavaScript 实用代码片段→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式