深入理解JS

119 阅读4分钟

1. 事件循环与异步编程

  • 事件循环(Event Loop) 是 JavaScript 最核心的机制之一,理解它有助于编写高效的异步代码。
  • 异步编程 是现代 JavaScript 编程的重要组成部分,尤其是在处理 I/O、网络请求、定时器等场景时。理解 Promiseasync/awaitcallback 的异同,对于掌握异步代码的执行顺序、避免回调地狱、以及提升代码的可读性和维护性非常重要。

示例:

 async function fetchData() {
   const response = await fetch('https://api.example.com/data');
   const data = await response.json();
   console.log(data);
 }
 fetchData();

2. 闭包(Closures)

  • 闭包 是 JavaScript 中非常常见且强大的特性,理解闭包有助于掌握作用域、变量提升、以及函数内部的变量捕获。
  • 闭包允许你在函数外部访问函数内部的变量,特别适用于构建私有数据和工厂函数等。

示例:

    function counter() {
      let count = 0;
      return function() {
        return ++count;
      };
    }
 ​
    const increment = counter();
    console.log(increment()); // 1
    console.log(increment()); // 2

3. 模块化与ES6模块(ESM)

  • 模块化 是组织代码的重要方式,ES6 引入的模块系统(importexport)为我们提供了结构化管理和复用代码的最佳实践。
  • 现代 JavaScript 开发中,几乎所有的项目都需要通过模块化来管理代码的逻辑分离、依赖管理等。

示例:

    // module.js
    export const greeting = 'Hello';
    export function greet(name) {
      return `${greeting}, ${name}`;
    }
 ​
    // main.js
    import { greet } from './module.js';
    console.log(greet('World')); // Hello, World

4. 原型与继承

  • 原型(Prototype) 是 JavaScript 的核心机制,理解它有助于掌握对象的继承、原型链,以及如何通过原型创建共享行为。
  • 现代 JavaScript 通过 类(Class)继承(Inheritance) 简化了原型的复杂性,但仍然是构建复杂对象系统的基础。

示例:

    class Animal {
      constructor(name) {
        this.name = name;
      }
      speak() {
        console.log(`${this.name} makes a sound.`);
      }
    }
 ​
    class Dog extends Animal {
      speak() {
        console.log(`${this.name} barks.`);
      }
    }
 ​
    const dog = new Dog('Buddy');
    dog.speak(); // Buddy barks.

5. 函数式编程(Functional Programming)

  • 虽然 JavaScript 不是纯函数式语言,但很多函数式编程概念在 JavaScript 中有很好的应用,如 柯里化(Currying)纯函数(Pure Functions)不可变性(Immutability) 等。
  • Array.map()Array.filter()Array.reduce() 等常见的高阶函数可以帮助简化数据操作过程。

示例:

    const numbers = [1, 2, 3, 4];
    const doubled = numbers.map(n => n * 2);
    console.log(doubled); // [2, 4, 6, 8]
 ​
    const sum = numbers.reduce((acc, n) => acc + n, 0);
    console.log(sum); // 10

6. 解构赋值(Destructuring Assignment)

  • 解构赋值 是 ES6 的语法糖,可以快速从数组或对象中提取值,并赋给变量,极大地提升了代码的可读性和简洁性。
  • 在处理复杂数据结构时,解构赋值可以让代码更加清晰、可维护。

示例:

    const person = { name: 'John', age: 30 };
    const { name, age } = person;
    console.log(name); // John
    console.log(age); // 30
 ​
    const numbers = [1, 2, 3];
    const [first, second] = numbers;
    console.log(first); // 1
    console.log(second); // 2

7. 异步迭代与 for await...of

  • 当处理异步数据流时(如处理分页数据或从 API 获取大量数据),你可以使用异步生成器和 for await...of 进行流式数据处理。它简化了对逐步获取的数据的处理,避免了嵌套的 thenawait 操作。

示例:

    async function* asyncGenerator() {
      for (let i = 0; i < 3; i++) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        yield i;
      }
    }
 ​
    (async () => {
      for await (let num of asyncGenerator()) {
        console.log(num); // 每秒输出 0, 1, 2
      }
    })();

8. Promise.all 和 Promise.race

  • Promise.allPromise.race 是处理多个异步操作的重要工具。
  • Promise.all 等待所有的 Promise 都完成,并返回结果数组;而 Promise.race 返回第一个完成的 Promise 的结果。

示例:

    const p1 = new Promise(resolve => setTimeout(resolve, 1000, 'one'));
    const p2 = new Promise(resolve => setTimeout(resolve, 2000, 'two'));
 ​
    Promise.all([p1, p2]).then(results => {
      console.log(results); // ['one', 'two'] after 2 seconds
    });
 ​
    Promise.race([p1, p2]).then(result => {
      console.log(result); // 'one' after 1 second
    });

9. Proxy 和 Reflect

  • ProxyReflect 是元编程工具,Proxy 可以拦截和自定义对象的操作(如属性访问、设置、删除等),而 Reflect 提供了执行对象操作的标准化方法。
  • 这些工具特别适合实现动态的行为控制,如响应式编程或数据监控。

示例:

    const handler = {
      get: (target, prop) => {
        console.log(`Accessing ${prop}`);
        return target[prop];
      }
    };
 ​
    const obj = { a: 1, b: 2 };
    const proxy = new Proxy(obj, handler);
    console.log(proxy.a); // Accessing a, 1

10. 事件委托(Event Delegation)

  • 事件委托 是提高页面性能的重要技术,尤其在处理大量 DOM 元素时,将事件绑定到父元素而不是每个子元素。
  • 事件冒泡机制使得父元素可以捕获子元素触发的事件,从而减少事件监听器的数量,提升性能。

示例:

 document.querySelector('#parent').addEventListener('click', function(event) {
   if (event.target.matches('.child')) {
     console.log('Child clicked:', event.target);
   }
 });

总结

  • 事件循环与异步编程(Promise、async/await)
  • 闭包
  • 模块化(ESM)
  • 函数式编程(高阶函数、不可变性)
  • 原型与继承
  • 解构赋值
  • 异步迭代与 for await...of
  • 事件委托
  • Proxy 和 Reflect