0
点赞
收藏
分享

微信扫一扫

加密与安全_深入了解哈希算法

攻城狮Chova 2024-03-06 阅读 6

JS的基本类型

JavaScript中的基本类型是指:那些存储在内存中的值类型,他们是不可以变的、意味着一旦创建,值类型就不能改变。

JS的7种基本类型

详细介绍

布尔值(Boolean)

布尔值只有两个:true或者false。它们通常用于表示条件或开关。

例如:

const isLoggedIn = true;

if (isLoggedIn) {
  // 用户已登录
} else {
  // 用户未登录
}
数字(Number)

数字可以是整数、浮点数或者NaN。

  • 整数:例如 123 等。
  • 浮点数:例如 1.23.14-0.5 等。
  • NaN:表示一个非数字值。

例如:

const age = 25;
const pi = 3.14;
const invalidNumber = NaN;

console.log(age + pi); // 28.14
console.log(invalidNumber / 2); // NaN
字符串(String)

字符串是一串字符的集合。它们可以用单引号、双引号或反引号括起来。

例如:

const name = "John Doe";
const message = "Hello, world!";
const multilineString = `This is a
multiline string.`;

console.log(name + " says " + message); // John Doe says Hello, world!
console.log(multilineString);
空(Null)

空值表示一个空值。它与未定义不同,未定义表示一个变量未赋值。

例如:

const variable = null;

console.log(variable === undefined); // false
console.log(variable === null); // true
未定义(Undefined)

未定义表示一个变量未赋值。

例如:

let variable;

console.log(variable); // undefined
Symbol

Symbol是ES6引入的一种新的数据类型,它表示一个独一无二的值。Symbol值通常用于表示对象的属性键(key)或者私有成员。

例如:

const symbol1 = Symbol();
const symbol2 = Symbol();

console.log(symbol1 === symbol2); // false

const object = {
  [symbol1]: "Hello",
  [symbol2]: "World"
};

console.log(object[symbol1]); // Hello
console.log(object[symbol2]); // World
BigInt

BigInt 是 ES2020(ES11) 中引入的一种新数据类型。它表示一个任意精度的整数。

例如:

const bigInt = 12345678901234567890n;

console.log(bigInt.toString()); // 12345678901234567890

BigInt的扩展

JS的引用类型

在JavaScript中引用类型是指:那些存储在堆内存中的对象,它们是可变的,这意味这一旦创建,他们的值就可以被改变。

JS的常见引用类型:

详细介绍

对象(Object)

对象是 JavaScript 中最基本的引用类型,它是一种无序的集合,由键值对(key-value pairs)组成。对象的键是字符串类型,值可以是任意类型的数据,包括基本类型和其他引用类型。

例如:

const person = {
  name: "John Doe",
  age: 25,
  address: {
    city: "New York",
    state: "NY",
    zip: "10001"
  }
};
数组(Array)

数组是一种特殊的对象,用来存储有序的数据集合。数组的每个元素可以是任意类型的数据,包括基本类型和其他引用类型。

例如:

const numbers = [1, 2, 3, 4, 5];
const fruits = ["apple", "banana", "orange"];
函数(Function)

函数是一种特殊的对象,它可以被调用执行代码。函数可以接受参数并返回值,也可以作为对象的属性和方法使用。

例如:

function add(a, b) {
  return a + b;
}

const result = add(1, 2); // 3
日期(Date)

Date 类型用来表示日期和时间。它是 JavaScript 中的内置对象,可以创建表示特定日期和时间的实例。

例如:

const date = new Date();
console.log(date.toString()); // "Thu Feb 16 2023 20:07:12 GMT+0800 (中国标准时间)"
正则表达式(RegExp)

正则表达式是一种用于匹配字符串模式的对象。它可以用来搜索、替换和提取字符串中的特定部分。

例如:

const regex = /\d+/g;
const matches = regex.exec("The answer is 42"); // ["42"]
错误(Errror)

错误对象表示程序运行时发生的错误。

例如:

try {
  // 这里可能会发生错误
} catch (error) {
  // 处理错误
}

JS中引用类型的特殊性

  • 引用: 引用类型的值是通过引用传递的。这意味着对引用类型的赋值实际上是复制了对该对象的引用,而不是复制对象的本身。
  • 可变性: 引用类型的值是可以改变的。对引用类型属性的更改会影响所有引用该对象的变量。
  • 原型: 每个引用类型都具有一个原型对象,该对象包含该类型的所有默认属性和方法。

箭头函数和普通函数的区别

箭头函数和普通函数的区别主要包括:语法、this绑定、arguments对象、构造函数、prototype等5个方面有区别;

  • 语法

    箭头函数使用"=>"来定义函数,普通函数则使用function关键字来进行定义。

    例如:

function add(a, b) {
    return a + b;
}

const add = (a, b) => a + b;
  • this指向

    箭头函数的this指向始终是定义时的上下文对象,而普通函数的this指向会根据调用方式发生变化。

    例如:

const obj = {
  name: 'obj',
  add: function(a, b) {
    console.log(this.name);
    return a + b;
  }
};

const add = (a, b) => {
  console.log(this.name);
  return a + b;
};

obj.add(1, 2); // 'obj'
add(1, 2); // undefined
  • arguments对象

    箭头函数中没有arguments对象,而普通函数中则可以通过arguments对象访问函数的参数列表。

​ 例如:

const add = function(a, b) {
  console.log(arguments);
  return a + b;
};

const add = (a, b) => {
  console.log(arguments); // ReferenceError: arguments is not defined
  return a + b;
};

add(1, 2);
  • 构造函数

    箭头函数不能作为构造函数使用,而普通函数则可以。

    例如:

const Person = function(name) {
  this.name = name;
};

const Person = () => {
  this.name = name;
};

const person = new Person('John'); // TypeError: Arrow functions cannot be used as constructors
  • prototype属性

    箭头函数没有prototype属性,而普通函数则可以通过prototype属性为函数添加方法。
    例如:

const Person = function(name) {
  this.name = name;
};

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person = new Person('John');
person.sayHello(); // 'Hello, my name is John'

const Person = () => {
  this.name = name;
};

const person = new Person('John');
person.sayHello(); // TypeError: person.sayHello is not a function

总结来说,箭头函数和普通函数各有优缺点。箭头函数语法更加简洁,this指向更加明确,但不能作为构造函数使用,没有prototype属性,也不能使用yield命令。普通函数功能更加强大,但语法更加繁琐,this指向容易混淆。在实际开发中,应根据具体需求选择合适的函数定义方式。

深拷贝和浅拷贝的区别

浅拷贝和深拷贝是常见的两种不同的对象复制方式。它们的主要区别在于浅拷贝只复制对象的引用,深拷贝则会复制对象的整个值,包括所有的属性和子对象。

浅拷贝

浅拷贝是指将一个对象的引用赋值给另一个对象,这就意味着两个对象将会指向同一个内存地址,如果修改一个对象的属性,另一个对象的属性也会随之改变。

深拷贝

深拷贝是指创建一个新的对象,并将其所有属性和子对象的值复制到一个新的对象中。这意味着两个对象拥有完全不同的内存地址,互不影响。

浅拷贝和深拷贝区别

区别浅拷贝深拷贝
复制方式复制引用复制值
内存地址相同不同
修改影响相互影响互不影响

例如:

// 原对象
const originalObj = {
    name: 'John',
    age: 30,
    hobbies: ['reading', 'music']
};

// 浅拷贝
const shallowCopyObj = Object.assign({}, originalObj);
shallowCopyObj.hobbies.push('sports');

console.log(originalObj.hobbies); // ['reading', 'music', 'sports']
console.log(shallowCopyObj.hobbies); // ['reading', 'music', 'sports']

// 深拷贝
const deepCopyObj = JSON.parse(JSON.stringify(originalObj));
deepCopyObj.hobbies.push('drawing');

console.log(originalObj.hobbies); // ['reading', 'music', 'sports']
console.log(deepCopyObj.hobbies); // ['reading', 'music', 'drawing']

如何实现深拷贝

在 JavaScript 中,可以通过以下几种方式实现深拷贝:

  • 使用 JSON.parse() 和 JSON.stringify() 方法
  • 使用递归函数
  • 使用第三方库
JSON.parse() 和 JSON.stringify() 方法

JSON.parse() 和 JSON.stringify() 方法可以将对象转换为 JSON 字符串,然后再将 JSON 字符串解析为对象。这种方法可以实现深拷贝,但需要注意的是,它会忽略对象的原型和循环引用。

递归函数

使用递归函数可以实现深拷贝。递归函数会遍历对象的每个属性,并将其值复制到新对象中。这种方法可以实现深拷贝,但需要注意的是,它可能会递归调用,导致性能问题。

例如:

function deepCopy(obj, visited =  new WeakMap()) {
    // 基本类型或 null,直接返回
    if (typeof obj !== 'object' || obj === null)   return obj;
    
    // 如果已拷贝的对象则直接进行返回
    if (visited.has(obj)) return visited.get(obj);
    
    // 对日期类型和正则表达式进行特殊处理,直接复制构造函数
    if (obj instanceof Date || obj instanceof RegExp) return new obj.constructor(obj);
    
    let copy = Array.isArray(obj) ? [] : {}; // 创建目标对象
    
    visited.set(obj, copy); // 记录已拷贝的对象
    
    for (let key in obj) { // 遍历对象的属性
        // 只复制自身属性,非原型链上的属性
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            copy[key] = deepCopy(obj[key], visited); // 递归拷贝
        }
    }
    
    return copy;
}
第三方库

可以使用第三方库来实现深拷贝。例如,Underscore.js 和 Lodash 都提供了深拷贝的方法。

类组件和函数式组件的区别

在React中,有两种创建组件的方式,一种式类组件,一种是函数式组件。类组件是使用ES6类创建的,而函数是组件是使用JavaScript函数进行创建的。

类组件

使用ES6类进行创建,并集成于React.Component类。同时具有一下特点:

  • 具有生命周期
  • 可以使用状态
  • 可以使用this关键字访问组件示例
函数式组件

函数式组件是React中较新类型的组件,React 16.8新增的特性。它使用JS函数进行创建,但是没有生命周期和状态。

  • 没有生命周期
  • 没有状态
  • 不能使用this访问组件实例
类组件和函数式组件的区别

以下是类组件和函数式组件的主要区别:

特性类组件函数式组件
创建方式使用 ES6 类使用 JavaScript 函数
继承继承自 React.Component
生命周期方法具有生命周期方法无生命周期方法
状态可以使用状态不能使用状态
this 关键字可以使用 this 关键字访问组件实例不能使用 this 关键字访问组件实例
性能性能略差性能略好
可读性可读性略差可读性略好
选择类组件还是函数式组件

因该考虑以下几点因素:

  • 组件是否需要状态
  • 组件是否需要生命周期方法
  • 组件的复杂度
  • 代码的可读性

闭包的理解

在JS中,闭包是指一个函数可以访问其外部函数的作用域中的变量,换句话说,闭包使函数能够记住其创建时的环境。

闭包的形成

闭包是在函数内部定义另一个函数时形成的,内部函数可以访问外部函数作用域中的变量,即使外包函数已经执行完毕。

闭包的示例
function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }
  return inner;
}

const fn = outer();

fn(); // 1
fn(); // 2

console.log(count); // undefined

在这个例子中,inner 函数是一个闭包,它可以访问外部函数 outer 中的变量 count。即使 outer 函数已经执行完毕,inner 函数仍然可以访问 count 变量。

闭包的优点
  • 可以进行封装代码,提高代码的可重用性
  • 可以实现私有变量,提高代码的安全性
  • 可以模拟面向对象编程中的类
闭包的缺点
  • 可能会导致内存泄漏
  • 可能会使代码变得难以理解
闭包的应用场景
  • 实现延迟执行

    function delay(fn, delay) {
      return setTimeout(fn, delay);
    }
    
    const fn = () => console.log("Hello");
    
    delay(fn, 1000); // 1秒后输出 "Hello"
    
  • 模拟面向对象编程中的类

    function Person(name) {
      this.name = name;
    
      const sayHello = () => console.log(`Hello, my name is ${this.name}`);
    
      return {
        sayHello,
      };
    }
    
    const person = new Person("John Doe");
    
    person.sayHello(); // 输出 "Hello, my name is John Doe"
    
  • 创建私有变量

    function counter() {
      let count = 0;
    
      function increment() {
        count++;
      }
    
      function getCount() {
        return count;
      }
    
      return {
        increment,
        getCount,
      };
    }
    
    const counter = counter();
    
    counter.increment();
    counter.increment();
    
    console.log(counter.getCount()); // 2
    
  • 实现事件监听

    function addEventListener(element, type, listener) {
      element.addEventListener(type, listener);
    
      return () => element.removeEventListener(type, listener);
    }
    
    const element = document.getElementById("button");
    
    const removeListener = addEventListener(element, "click", () => console.log("Button clicked"));
    
    // 移除事件监听
    removeListener();
    

Promise详解

Promise是ES6中引入的一种用于处理异步操作的对象。它代表了一个异步操作的最终完成(或者失败)及其结果的表示。

Promise状态

  • Pending(进行中): 初始状态,表示异步操作尚未完成,正在进行中。
  • Fulfilled(已完成): 表示异步操作已经完成
  • Rejected(已拒绝): 表示异步操作失败

Promise状态更改

Promise的状态只能由resolve和reject进行更改。

  • resolve函数将Promise的状态更改为Fulfilled,并且传入一个结果作为值。
  • reject函数将Promise的状态更改为Rejected,并转入一个错误对象作为原因。

Promise状态改变之后不可以逆转!

Promise状态实列:

const promise =  new Promise((resolve, reject) => {
    setTimeOut(() => {
        resolve('success');
    }, 1000);
});

promise.then(
    (reslut) => {
        console.log(reslut); // 'success'
    }, 
    (error) => {
        console.log(error);
    }
);

​ 在这个例子中,Promise 的初始状态是 Pending。1 秒后,resolve 函数被调用,将 Promise 的状态更改为 Fulfilled,并传入 success 作为结果。然后,then 方法的第一个回调函数被调用,并输出 success

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('error');
  }, 1000);
});

promise.then(
  (result) => {
    console.log(result);
  },
  (error) => {
    console.log(error); // 'error'
  }
);

​ 在这个例子中,Promise 的初始状态是 Pending。1 秒后,reject 函数被调用,将 Promise 的状态更改为 Rejected,并传入 error 作为原因。然后,then 方法的第二个回调函数被调用,并输出 error

Promise场景

  • ajax请求
  • setTimeOut
  • setInterval
  • Web API

Promise特点

  • 不可变性: 一旦状态变为 Fulfilled 或 Rejected,就不会再改变。
  • 链式调用: 可以通过 then() 方法进行链式调用,依次处理异步操作的成功或失败情况。
  • 错误捕获: 可以通过 catch() 方法捕获异步操作中的错误。

Promise基本使用

Promise创建

const promise = new Promise((resolve, reject) => {
  // 异步操作
});

new Promise 语句接受一个函数作为参数,该函数有两个参数:

  • resolve:用于将 Promise 的状态更改为 Fulfilled 的函数。
  • reject:用于将 Promise 的状态更改为 Rejected 的函数。
let promise = new Promise((resolve, reject) => {
    // 异步操作
    if (/* 异步操作成功 */) {
        resolve("操作成功"); // 将 Promise 状态从 Pending 变为 Fulfilled
    } else {
        reject("操作失败"); // 将 Promise 状态从 Pending 变为 Rejected
    }
});

// 第一种写法(个人喜欢这种写法,使用命名函数来处理成功和失败,可读性高,方便代码重用)
promise.then((result) => {
    console.log("成功:" + result);
}).catch((error) => {
    console.error("失败:" + error);
});

// 第二种写法(使用匿名函数处理成功和失败)
promise.then(
 (result) => {
    // 处理成功结果
  },
  (error) => {
    // 处理失败结果
  }
);

// 第三种写法(使用命名函数处理结果)
function handleSuccess(result) {}
function handleError(error) {}
promise.then(handleSuccess, handleError);

Promise常见用法

串联执行

使用then方法可以将多个异步操作串联起来。

const promise1 = new Promise((resolve, reject) => {
  // 异步操作 1
});

const promise2 = new Promise((resolve, reject) => {
  // 异步操作 2
});

promise1.then(() => {
  return promise2;
}).then((result) => {
  // 处理最终结果
});

也可以理解为嵌套执行。

Promise 嵌套是指在一个 Promise 实例的 then 方法中,又返回一个新的 Promise 实例。这种嵌套可以用于处理多个异步操作的依赖关系。

以下是一个简单的 Promise 嵌套示例:

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success1');
  }, 1000);
});

promise1.then((result) => {
  console.log('promise1 成功fulfilled:', result);
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('success2');
    }, 2000);
  });
}).then((result) => {
  console.log('promise2 成功fulfilled:', result);
});

串联执行的注意事项:

  • Promise 嵌套会导致代码结构变得复杂,因此需要谨慎使用。
  • 在使用 Promise 嵌套时,需要考虑错误处理的情况。
  • 如果嵌套层级过深,可能会导致性能问题。

Promise 嵌套的替代方案

  • 使用 async/await 语法
  • 使用 Promise.all 方法
  • 使用 Promise 的静态方法 Promise.resolvePromise.reject
并行执行

可以使用 Promise.all 方法并行执行多个异步操作。

const promise1 = new Promise((resolve, reject) => {
  // 异步操作 1
});

const promise2 = new Promise((resolve, reject) => {
  // 异步操作 2
});

Promise.all([promise1, promise2]).then((results) => {
  // 处理所有结果
});
const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success2');
  }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('error');
  }, 3000);
});

const allPromise = Promise.all([promise1, promise2, promise3]);

allPromise.then(
  (results) => {
    console.log('所有 Promise 实例都成功fulfilled:', results);
  },
  (error) => {
    console.error('其中一个 Promise 实例被 rejected:', error);
  }
);

Promise.all 的返回值

Promise.all 方法返回的新 Promise 实例的返回值取决于传入的 Promise 实例的状态:

  • 如果所有传入的 Promise 实例都成功 fulfilled,则新的 Promise 实例会成功 fulfilled,并返回一个包含所有 Promise 实例的成功结果的数组。
  • 如果其中一个 Promise 实例被 rejected,则新的 Promise 实例会立即被 rejected,并返回第一个被 rejected 的 Promise 实例的错误原因。

Promise.all 的注意事项

  • Promise.all 方法只会等待所有传入的 Promise 实例都完成,不会根据传入的顺序执行它们。
  • Promise.all 方法不会改变传入 Promise 实例的状态。
  • 如果传入的 Promise 实例不是一个可迭代对象,则 Promise.all 方法会抛出一个 TypeError 错误

关于返回结果是否有先后顺序

Promise.all 方法返回的新 Promise 实例的返回值是一个数组,该数组的顺序与传入 Promise 实例的顺序一致

竞速执行

Promise.race() 是 Promise 提供的一个静态方法,用于在多个 Promise 实例中,只要有一个实例率先改变状态(无论是 Fulfilled 还是 Rejected),就返回那个率先改变状态的 Promise 实例的返回值。换句话说,Promise.race() 用于竞速,返回最先完成的 Promise 的结果或错误。

let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("promise1 resolved");
    }, 1000);
});

let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("promise2 resolved");
    }, 500);
});

Promise.race([promise1, promise2]).then((result) => {
    console.log(result); // 输出 "promise2 resolved"
});
错误处理

可以使用 catch 方法处理 Promise 的错误。

promise.then(
  (result) => {
    // 处理成功结果
  }
).catch((error) => {
  // 处理失败结果
});
最终处理

finally 方法:无论 Promise 成功或失败,finally 方法都会被调用。

promise.then(
  (result) => {
    // 处理成功结果
  },
  (error) => {
    // 处理失败结果
  }
).finally(() => {
  // 无论成功或失败都会执行的代码
});

Promise扩展

PromiseFetchAjax 都是 JavaScript 中用于处理异步操作的技术。它们之间存在一些关键的区别:

Promise

Promise 是 JavaScript 中用于处理异步操作的对象。它可以使异步代码更加易读易写,并帮助你避免回调地狱。

Promise 的主要特点:

  • 可以将异步操作的结果封装成一个对象
  • 可以使用 then 方法来处理异步操作的结果
  • 可以使用 catch 方法来处理异步操作的错误
  • 可以使用 finally 方法来执行一些无论成功或失败都会执行的代码
Fetch

Fetch 是 JavaScript 中用于发送 HTTP 请求的 API。它比传统的 XMLHttpRequest API 更易于使用,并提供了更多的功能。

Fetch 的主要特点:

  • 使用 Promise 来处理请求的结果
  • 支持多种 HTTP 方法
  • 支持请求头和响应头
  • 支持流式数据传输
Ajax

Ajax 是 Asynchronous JavaScript and XML 的缩写,是一种使用 JavaScript 在不刷新页面的情况下与服务器通信的技术。

Ajax 的主要特点:

  • 使用 XMLHttpRequest 对象来发送 HTTP 请求
  • 使用回调函数来处理请求的结果
  • 可以用于发送 GET、POST、PUT、DELETE 等 HTTP 方法
  • 可以用于加载数据、更新页面内容等
比较
特性PromiseFetchAjax
用途处理异步操作发送 HTTP 请求与服务器通信
返回值Promise 对象Promise 对象XMLHttpRequest 对象
处理结果then 方法then 方法回调函数
错误处理catch 方法catch 方法错误回调函数
优势易读易写,避免回调地狱简洁易用,功能强大兼容性好,支持多种浏览器
劣势嵌套层级过深会导致性能问题不支持 IE 9 及更早版本代码结构混乱,难以维护
总结

Promise、Fetch 和 Ajax 都是用于处理异步操作的技术。它们各有优势,适合不同的场景。

  • 如果需要处理通用的异步操作,可以使用 Promise。
  • 如果需要发送 HTTP 请求,可以使用 Fetch。
  • 如果需要兼容旧浏览器,可以使用 Ajax。

建议根据实际需求选择合适的技术。

Vue3中diff算法的认识

Vue3 Diff 算法详细介绍

Vue3中的Diff算法是一种用于计算虚拟DOM树差异的算法,它用于在更新数据时尽可能高效地更新真实DOM。

DIFF算法的核心思想是最小路径更新,即只更新虚拟dom中受数据影响的最小部分。实现步骤:

  1. 深度优先遍历虚拟DOM树:从根节点开始,深度优先遍历虚拟DOM树,同时每个节点生成一个唯一的Key。
  2. 比较新旧虚拟DOM树:使用key匹配新旧虚拟DOM树中的节点,如果节点的 key 相同,则比较它们的属性和子节点。如果节点的 key 不同,则认为该节点已删除或新增。
  3. 生成更新操作列表:根据新旧虚拟 DOM 树的差异,生成一个更新操作列表。更新操作包括:
    • 插入节点
    • 删除节点
    • 更新节点属性
    • 移动节点
  4. 应用更新操作:根据更新操作列表,更新真实 DOM。

Vue3 Diff 算法相比 Vue2 中的 Diff 算法有以下改进:

  • 更快: 由于采用了“最小路径更新”的思想,Vue3 Diff 算法可以只更新受数据更新影响的最小部分虚拟 DOM 树,因此速度更快。
  • 更少内存使用: Vue3 Diff 算法不再使用“最小公共子序列”算法来比较两个虚拟 DOM 树,因此内存使用更少。
  • 更易于理解: Vue3 Diff 算法的实现更加简单易懂。
Vue3 Diff 算法示例

以下示例演示了 Vue3 Diff 算法如何工作:

<div id="app">
  <p>{{ count }}</p>
  <button @click="increment">+</button>
</div>
const app = Vue.createApp({
  data() {
    return {
      count: 0,
    };
  },
  methods: {
    increment() {
      this.count++;
    },
  },
});

app.mount("#app");

初始状态下,虚拟 DOM 树如下:

<div id="app">
  <p>0</p>
  <button>+</button>
</div>

当用户点击按钮时,count 值增加 1,虚拟 DOM 树变为:

<div id="app">
  <p>1</p>
  <button>+</button>
</div>

Vue3 Diff 算法会计算两个虚拟 DOM 树之间的差异,并生成更新操作列表。更新操作列表如下:

[
  {
    type: "update",
    node: {
      id: "app",
    },
    attr: {
      textContent: "1",
    },
  },
]

根据更新操作列表,Vue3 会更新真实 DOM,将文本内容更新为 “1”。

总结:Vue3 Diff 算法是一种高效的虚拟 DOM 树差异计算算法,它可以使 Vue3 在更新数据时更加高效。

举报

相关推荐

0 条评论