每日三问-前端(第三十期)

先来回顾一下上期的问题及答案:

1. 手写一个深拷贝

深拷贝是指创建一个新对象,将原始对象的所有属性递归地复制到新对象中,包括嵌套对象和数组。以下是一个手写深拷贝的示例代码:

function deepClone(obj: any): any {
  if (obj === null || typeof obj !== 'object') {
    return obj; // 非对象或 null 直接返回
  }

  let clone: any;
  if (Array.isArray(obj)) {
    clone = [];
    for (let i = 0; i < obj.length; i++) {
      clone[i] = deepClone(obj[i]); // 递归复制数组元素
    }
  } else {
    clone = {};
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        clone[key] = deepClone(obj[key]); // 递归复制对象属性
      }
    }
  }

  return clone;
}

上述代码通过递归的方式实现了深拷贝,可以处理对象和数组的情况,保证了每个属性的值都是独立的。

2. 讲解 Promise.allPromise.racePromise.allSettled 的相同与不同

这三个方法都是 JavaScript 中用于处理 Promise 的方法,下面对它们进行详细解释:

  1. Promise.all:接收一个 Promise 数组作为参数,并返回一个新的 Promise。只有当所有的 Promise 都变为 resolved 状态时,新的 Promise 才会变为 resolved 状态,返回值是一个包含所有 Promise 结果的数组。如果其中一个 Promise 变为 rejected 状态,新的 Promise 就会立即变为 rejected 状态。

const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // 输出:[1, 2, 3]
  })
  .catch((error) => {
    console.error(error);
  });
  1. Promise.race:接收一个 Promise 数组作为参数,并返回一个新的 Promise。只要其中一个 Promise 变为 resolved 或 rejected 状态,新的 Promise 就会立即变为相同的状态,并返回相应的值。

const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, 'one'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 2000, 'two'));

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // 输出:'one'
  })
  .catch((error) => {
    console.error(error);
  });
  1. Promise.allSettled:接收一个 Promise 数组作为参数,并返回一个新的 Promise。无论 Promise 是 resolved 还是 rejected,新的 Promise 都会变为 resolved 状态,返回值是一个包含每个 Promise 结果的对象数组,每个对象包含 statusvalue 属性,表示 Promise 的状态和结果。

const promise1 = Promise.resolve(1);
const promise

2 = Promise.reject('error');

Promise.allSettled([promise1, promise2])
  .then((results) => {
    console.log(results);
    // 输出:
    // [
    //   { status: 'fulfilled', value: 1 },
    //   { status: 'rejected', reason: 'error' }
    // ]
  })
  .catch((error) => {
    console.error(error);
  });

相同点:

  • 都是用于处理 Promise 的方法,接收一个 Promise 数组作为参数。

  • 返回一个新的 Promise 对象。

不同点:

  • Promise.all 要求所有 Promise 都变为 resolved 状态才会返回结果,一旦其中一个 Promise 变为 rejected 状态,整个 Promise 就会立即变为 rejected 状态。

  • Promise.race 只要其中一个 Promise 变为 resolved 或 rejected 状态,整个 Promise 就会立即返回相应的结果。

  • Promise.allSettled 不管 Promise 是 resolved 还是 rejected,都会返回结果,每个 Promise 的状态和结果都会被记录下来。

3. TypeScript 中的 unknown 类型应用场景

unknown 是 TypeScript 中的顶级类型,它表示一个未知类型的值。与 any 类型不同,unknown 类型是类型安全的,不能直接访问其属性或调用其方法,除非经过类型断言或类型保护。unknown 类型的应用场景包括:

  1. 动态数据解析:当需要处理从外部源(如 API 响应或用户输入)获取的数据时,通常无法事先确定其结构和类型,此时可以将其标记为 unknown 类型,并使用类型断言或类型保护来处理数据的解析。

function parseData(data: unknown): void {
  if (typeof data === 'string') {
    console.log(data.toUpperCase());
  } else if (Array.isArray(data)) {
    console.log(data.length);
  } else {
    console.log('Unknown data type');
  }
}

parseData('hello'); // 输出:HELLO
parseData([1, 2, 3]); // 输出:3
parseData({}); // 输出:Unknown data type
  1. 存储动态类型数据:当需要存储可以是多种类型的数据时,可以使用 unknown 类型来灵活处理。

let dynamicData: unknown;

dynamicData = 'hello';
console.log(typeof dynamicData); // 输出:string

dynamicData = 123;
console.log(typeof dynamicData); // 输出:number

dynamicData = true;
console.log(typeof dynamicData); // 输出:boolean
  1. 异常情况处理:当处理可能引发异常或未知错误的操作时,可以使用 unknown 类型来捕获异常,并提供适当的错误处理机制。

try {
  // 可能会抛出异常的操作
} catch (error: unknown) {
  console.error('An error occurred:', error);
}

总之,unknown 类型在 TypeScript 中用于表示未知类型的值,适用于需要处理动态数据、存储动态类型数据或处理异常情况的场景。使用 unknown 类型可以提

供更好的类型安全性和编码规范性。

2023年6月28日

  1. 问题:什么是 TypeScript?它与 JavaScript 有什么区别?请列举 TypeScript 的一些特性和优势。

  2. 问题:什么是类型断言(Type Assertion)?请解释类型断言的作用和用法,并提供一个示例。

  3. 问题:什么是泛型(Generics)?请解释泛型的概念和用途,并给出一个使用泛型的例子。

上面问题的答案会在第二天的公众号推文中公布,大家可以关注公众号:程序员每日三问,第一时间获得推送内容。

学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题(死磕自己,愉悦大家) 希望大家在这浮夸的程序员圈里保持冷静,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值