Vue和JavaScript中常用的设计模式

1. 观察者模式(Observer Pattern)

  • Vue 中的应用:Vue.js 中的响应式系统就是基于观察者模式实现的。当数据变化时,所有依赖于该数据的地方都会得到通知并进行相应的更新。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // Vue中的观察者模式示例
    const vm = new Vue({
    data: {
    message: "Hello",
    },
    });

    vm.$watch("message", function (newVal, oldVal) {
    console.log(`message从${oldVal}变为${newVal}`);
    });

    vm.message = "Hello, Vue";

2. 发布-订阅模式(Pub/Sub Pattern)

  • Vue 中的应用:Vue.js 的事件机制使用了发布-订阅模式。组件可以通过$emit来发布事件,而通过$on来订阅事件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // Vue中的发布-订阅模式示例
    const eventBus = new Vue();

    // 订阅事件
    eventBus.$on("sayHello", function () {
    console.log("Hello from eventBus");
    });

    // 发布事件
    eventBus.$emit("sayHello");

3. 单例模式(Singleton Pattern)

  • JavaScript 中的应用:单例模式确保类只有一个实例,并提供一个全局访问点。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // JavaScript中的单例模式示例
    const Singleton = (function () {
    let instance;

    function createInstance() {
    return {
    name: "I am a singleton object",
    };
    }

    return {
    getInstance: function () {
    if (!instance) {
    instance = createInstance();
    }
    return instance;
    },
    };
    })();

    const instance1 = Singleton.getInstance();
    const instance2 = Singleton.getInstance();

    console.log(instance1 === instance2); // 输出 true

4. 工厂模式(Factory Pattern)

  • JavaScript 中的应用:工厂模式用于创建对象,隐藏具体的创建逻辑,并提供统一的接口。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // JavaScript中的工厂模式示例
    function Car(options) {
    this.brand = options.brand || "Unknown Brand";
    this.model = options.model || "Unknown Model";
    }

    function CarFactory() {}
    CarFactory.prototype.createCar = function (options) {
    return new Car(options);
    };

    const factory = new CarFactory();
    const myCar = factory.createCar({ brand: "Toyota", model: "Camry" });

设计模式在 Vue 和 JavaScript 中有着广泛的应用,能够帮助开发人员更好地组织代码结构、降低耦合度以及提高代码复用性。对于不同的场景和需求,选择合适的设计模式能够让代码更加健壮和可维护。

JavaScript中的数组遍历方法详解

在JavaScript中,有多种方法可以用来遍历数组。下面是一些常见的数组遍历方法:

  1. for循环:

    1
    2
    3
    4
    let arr = [1, 2, 3, 4, 5];
    for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
    }
  2. forEach()方法:

    1
    2
    3
    arr.forEach(function(item) {
    console.log(item);
    });
  3. map()方法:

    1
    2
    3
    let newArr = arr.map(function(item) {
    return item * 2;
    });
  4. for…of循环:

    1
    2
    3
    for (let item of arr) {
    console.log(item);
    }
  5. for…in循环(不推荐用于数组遍历):

    1
    2
    3
    for (let index in arr) {
    console.log(arr[index]);
    }
  6. filter()方法:

    1
    2
    3
    let filteredArr = arr.filter(function(item) {
    return item > 2;
    });
  7. reduce()方法:

    1
    2
    3
    let sum = arr.reduce(function(accumulator, currentValue) {
    return accumulator + currentValue;
    }, 0);

这些方法各自有其特点和适用场景。开发者可以根据实际情况选择合适的方法进行数组遍历和操作。

块级格式化上下文BFC

BFC(Block Formatting Context)是指块级格式化上下文,它是页面中的一块独立的渲染区域,内部元素的布局不会影响到外部元素。BFC 具有如下特性:

  1. 内部的盒子会在垂直方向一个接一个地放置。
  2. 垂直方向上的边距会发生折叠。
  3. BFC 的区域不会与浮动盒子重叠。
  4. BFC 是页面上一个独立的容器,容器内部的布局不会影响到外部元素。

应用场景:

  • 清除浮动:当父元素包含了浮动的子元素时,可以触发父元素的 BFC 特性来清除浮动,避免父元素高度塌陷的问题。
  • 避免边距重叠:当需要避免相邻块级元素的垂直边距重叠时,可以创建 BFC 来限制边距的传播。
  • 多栏布局:利用 BFC 可以实现多栏布局,其中每个列就是一个 BFC 区域,避免了多栏布局中的一些问题。

通过理解 BFC 的概念和应用场景,前端开发人员可以更好地处理布局方面的问题,并优化页面的渲染效果。

JavaScript事件循环和宏微队列

JavaScript 是一种单线程的语言,它使用事件循环来处理异步操作。事件循环包括宏任务队列和微任务队列,用于管理异步任务的执行顺序。

事件循环(Event Loop)

事件循环指的是 JavaScript 引擎用来处理任务的一种机制。当代码执行时,会产生同步任务和异步任务。事件循环负责维护这些任务的执行顺序,确保它们按照特定规则被逐个执行。

宏任务队列(Macro Task Queue)

宏任务队列存放着产生于 DOM 操作、setTimeout、setInterval 等异步任务,它们会在主线程上执行。当执行栈为空时,事件循环会从宏任务队列中取出一个任务并执行。

微任务队列(Micro Task Queue)

微任务队列用于存放 Promise、MutationObserver 等产生的微任务。与宏任务不同的是,微任务会在当前任务执行结束后立即执行,确保在下一个宏任务执行前被处理完毕。

执行流程

  1. 首先执行同步任务,将产生的异步任务放入相应的队列中;
  2. 当执行栈为空时,首先执行微任务队列中的所有任务;
  3. 微任务执行完毕后,执行下一个宏任务队列中的任务;
  4. 重复以上步骤,直到所有任务执行完毕。

通过事件循环、宏任务队列和微任务队列的配合,JavaScript 实现了高效的异步任务处理机制,确保了良好的用户体验和程序执行效率。

浏览器执行流程

浏览器从输入网址到最后的运行流程可以分为以下几个步骤:

  1. DNS 解析:浏览器首先会进行 DNS 解析,将输入的网址解析成对应的 IP 地址,以便与服务器建立连接。

  2. 建立 TCP 连接:一旦获得目标服务器的 IP 地址,浏览器会通过 TCP 协议与服务器建立连接。这通常包括三次握手过程,确保客户端和服务器之间建立可靠的连接。

  3. 发起 HTTP 请求:连接建立后,浏览器会向服务器发送 HTTP 请求,该请求中包含了请求的资源信息,例如网页文件、图片、样式表等。

  4. 服务器处理请求并返回响应:服务器收到请求后,会根据请求内容处理并返回相应的 HTTP 响应,包括状态码、响应头和响应体等信息。

  5. 浏览器解析响应:浏览器接收到服务器返回的响应后,会解析响应内容,如果是 HTML 页面,则浏览器会解析其中的文档结构和资源链接。

  6. 构建 DOM 树和渲染树:浏览器会根据 HTML 文档构建 DOM 树,并根据 CSS 样式构建渲染树,计算每个节点的大小、位置和样式等信息。

  7. 布局和绘制:浏览器使用渲染树中的信息对页面进行布局和绘制,计算每个元素在屏幕上的确切位置,并将其呈现给用户。

  8. 执行 JavaScript:如有 JavaScript 代码,浏览器会执行 JavaScript 以及与之相关的事件处理逻辑。

  9. 加载其他资源:在页面渲染完成之后,浏览器可能还需要加载其他资源,例如异步加载的图片、字体等内容。

  10. 显示页面:最终,浏览器会将最终的页面展示给用户,用户可以与页面交互,执行点击、滚动等操作。

这些步骤构成了从输入网址到网页最终展示的整个流程,涉及了网络通信、资源加载、页面解析和渲染等多个环节。