当前位置: 首页 > article >正文

JavaScript 高级教程:异步编程、面向对象与性能优化

在前两篇教程中,我们学习了 JavaScript 的基础和进阶内容。这篇文章将带领你进入更深层次,学习 JavaScript 的异步编程模型、面向对象编程(OOP),以及性能优化的技巧。这些内容对于构建复杂、流畅的前端应用至关重要。


一、异步编程

1. 异步编程模型简介

JavaScript 是单线程的,但它可以通过事件循环(Event Loop)机制实现异步操作。常见的异步方式包括:

  • 回调函数
  • Promise
  • async/await

2. Promise:优雅的异步解决方案

Promise 是异步操作的核心。它可以使代码从嵌套的回调地狱中解脱出来。

示例:

const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const success = true; // 模拟成功或失败
            if (success) {
                resolve("数据加载成功!");
            } else {
                reject("数据加载失败!");
            }
        }, 2000);
    });
};

fetchData()
    .then((data) => {
        console.log(data); // 输出:数据加载成功!
    })
    .catch((error) => {
        console.error(error); // 如果失败,输出:数据加载失败!
    });

要点

  • resolve 表示成功,reject 表示失败。
  • then 用于处理成功,catch 用于捕获错误。

3. async/await:更直观的异步写法

async/await 是对 Promise 的语法糖,代码更简洁。

示例:

const fetchData = () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => resolve("数据加载成功!"), 2000);
    });
};

const loadData = async () => {
    try {
        const data = await fetchData();
        console.log(data); // 输出:数据加载成功!
    } catch (error) {
        console.error(error); // 捕获错误
    }
};

loadData();

优点

  • 更像同步代码,易读性高。
  • try/catch 捕获错误。

4. 综合案例:加载用户数据

const fetchUserData = async () => {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/users");
        const users = await response.json(); // 转换为 JSON
        console.log(users); // 打印用户数据
    } catch (error) {
        console.error("数据加载失败:", error);
    }
};

fetchUserData();

二、面向对象编程(OOP)

1. JavaScript 中的类与对象

ES6 引入了 class 语法,使面向对象编程更简洁。

示例:

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    introduce() {
        console.log(`我是 ${this.name},今年 ${this.age} 岁。`);
    }
}

const alice = new Person("Alice", 25);
alice.introduce(); // 输出:我是 Alice,今年 25 岁。

要点

  • constructor 是构造函数,用于初始化对象属性。
  • 方法定义在 class 中,所有实例共享这些方法。

2. 继承

通过 extends 关键字实现类的继承。

示例:

class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} 发出了声音!`);
    }
}

class Dog extends Animal {
    speak() {
        console.log(`${this.name} 说:汪汪!`);
    }
}

const dog = new Dog("小狗");
dog.speak(); // 输出:小狗 说:汪汪!

要点

  • 子类可以重写父类的方法。
  • 子类中使用 super 调用父类方法或构造函数。

3. 封装与私有属性

通过私有属性隐藏内部实现细节,ES2021 引入了 # 作为私有属性的标志。

示例:

class BankAccount {
    #balance = 0; // 私有属性

    deposit(amount) {
        this.#balance += amount;
        console.log(`存入:${amount},余额:${this.#balance}`);
    }

    withdraw(amount) {
        if (amount > this.#balance) {
            console.log("余额不足!");
        } else {
            this.#balance -= amount;
            console.log(`取出:${amount},余额:${this.#balance}`);
        }
    }
}

const account = new BankAccount();
account.deposit(100); // 输出:存入:100,余额:100
account.withdraw(50); // 输出:取出:50,余额:50
// console.log(account.#balance); // 报错:无法访问私有属性

三、性能优化

在开发大型应用时,性能优化非常重要。以下是几种常见的优化技巧。


1. 减少 DOM 操作

频繁的 DOM 操作会降低性能,建议批量更新 DOM 或使用虚拟 DOM。

示例:

// 使用文档片段批量操作 DOM
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
    const div = document.createElement("div");
    div.textContent = `第 ${i + 1} 个元素`;
    fragment.appendChild(div);
}
document.body.appendChild(fragment);

2. 使用节流(throttle)和防抖(debounce)

节流防抖用于优化高频触发的事件(如滚动或输入)。

节流:限制触发频率

const throttle = (func, delay) => {
    let last = 0;
    return (...args) => {
        const now = Date.now();
        if (now - last >= delay) {
            last = now;
            func(...args);
        }
    };
};

window.addEventListener("resize", throttle(() => {
    console.log("窗口大小变化!");
}, 500));

防抖:延迟执行

const debounce = (func, delay) => {
    let timer;
    return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => func(...args), delay);
    };
};

document.getElementById("search").addEventListener("input", debounce(() => {
    console.log("用户正在输入...");
}, 300));

3. 异步加载资源

通过异步加载外部资源(如脚本或图片)提升页面加载速度。

示例:

<script src="large-script.js" async></script>
<script src="analytics.js" defer></script>
  • async:脚本异步加载并立即执行。
  • defer:脚本异步加载,但延迟到 DOM 完全解析后执行。

4. 使用 Web Workers

Web Workers 可将复杂计算移至后台线程,避免阻塞主线程。

示例:

// worker.js
self.onmessage = (event) => {
    const result = event.data * 2;
    self.postMessage(result);
};

// 主线程
const worker = new Worker("worker.js");
worker.postMessage(5);
worker.onmessage = (event) => {
    console.log("计算结果:", event.data); // 输出:10
};

四、综合案例:简单搜索框

功能描述

  • 用户输入内容时,动态搜索匹配结果。
  • 防止高频搜索请求。

HTML

<input type="text" id="search" placeholder="搜索...">
<ul id="results"></ul>

JavaScript

const results = document.getElementById("results");
const debounce = (func, delay) => {
    let timer;
    return (...args) => {
        clearTimeout(timer);
        timer = setTimeout(() => func(...args), delay);
    };
};

const search = async (query) => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/users?name_like=${query}`);
    const users = await response.json();
    results.innerHTML = users.map(user => `<li>${user.name}</li>`).join("");
};

document.getElementById("search").addEventListener("input", debounce((event) => {
    const query = event.target.value.trim();
    if (query) {
        search(query);
    } else {
        results.innerHTML = "";
    }
}, 300));

五、总结与下一步

通过本文,你学习了:

  1. 异步编程的多种方式(回调、Promise、async/await)。
  2. 面向对象编程的核心概念(类、继承、封装)。

能优化的常见技巧(节流、防抖、Web Workers)。

下一步

  • 学习如何使用 JavaScript 框架(如 React、Vue)构建复杂应用。
  • 探索服务端 JavaScript(Node.js)进行全栈开发。

掌握这些内容后,你将具备构建高效、健壮 Web 应用的能力!


http://www.kler.cn/a/418890.html

相关文章:

  • STM32的CAN波特率计算
  • 网络安全防护指南:筑牢网络安全防线(5/10)
  • 使用Dify与BGE-M3搭建RAG(检索增强生成)应用-改进一,使用工作流代替Agnet
  • Web 端网站后台裁剪功能:提升图像管理效率的利器
  • JS听到了双生花的回响
  • 实时数据开发|Flink实现数据输出--DataSinks操作
  • EC2还原快照
  • 探索3D世界:使用 lib3ds 读取和解析 3DS 文件
  • CentOS使用chrony服务进行时间同步源设置脚本
  • CSS3网站
  • 欧拉函数——acwing
  • 挑战用React封装100个组件【005】
  • 【linux】(23)对象存储服务-MinIo
  • Linux 僵尸进程和孤儿进程, 进程优先级
  • Android 12.0新增自定义HIDL问题记录
  • 内网穿透步骤
  • Spring Data JPA(二) 高级进阶
  • linux——进程间通信及管道的应用场景
  • 蓝桥杯经验分享
  • 医院分诊管理系统|Java|SSM|VUE| 前后端分离
  • 2. STM32_中断
  • 深入理解 PyTorch .pth 文件和 Python pickle 模块:功能、应用及实际示例
  • 前端学习week8——vue.js
  • 支持向量机算法:原理、实现与应用
  • LeetCode题解:34.在排序数组中查找元素的第一个和最后一个位置【Python题解超详细,二分查找法、index法】,知识拓展:index方法详解
  • [MySQL]流程控制语句