前端技术学习遇到的一些知识点汇总

129 阅读2分钟

1、Promise.all

在平时的开发中,我们涉及到多个异步方法执行的时候,我们可以利用Promise.all来做,它会按照输入的数组顺序返回一个有序的结果数组,但是有序的结果并不代表有序的执行

// 多个promise
const promises = [...]

Promise.all(promises).then(res => {
  console.log(res)
  // [.....] 结果
})

如果想做到多个异步请求的同步执行方式,可以利用for(let p of promises)的方法,但是会引起eslint的报错

可以利用reduce的方法更加优雅的解决这个问题

promises.reduce(
	(prev, next) => prev.then(() => next.action()), 
	Promise.resolve()
);

2、ES2022相关知识

Object.hasOwn()

在ES2022之前,可以使用 Object.prototype.hasOwnProperty() 来检查一个属性是否属于对象。

Object.hasOwn 特性是一种更简洁、更可靠的检查属性是否直接设置在对象上的方法:

const example = {
  property: '123'
};

console.log(Object.prototype.hasOwnProperty.call(example, 'property'));
console.log(Object.hasOwn(example, 'property'));

at()

at() 是一个数组方法,用于通过给定索引来获取数组元素。当给定索引为正时,这种新方法与使用括号表示法访问具有相同的行为。当给出负整数索引时,就会从数组的最后一项开始检索:

const array = [0,1,2,3,4,5];

console.log(array[array.length-1]);  // 5
console.log(array.at(-1));  // 5

console.log(array[array.lenght-2]);  // 4
console.log(array.at(-2));  // 4

除了数组,字符串也可以使用at()方法进行索引:

const str = "hello world";

console.log(str[str.length - 1]);  // d
console.log(str.at(-1));  // d

私有实例字段、方法和访问器

默认情况下,ES6 中所有属性都是公共的,可以在类外检查或修改。下面来看一个例子:

class TimeTracker {
  name = 'zhangsan';
  project = 'blog';
  hours = 0;

  set addHours(hour) {
    this.hours += hour;
  }

  get timeSheet() {
    return `${this.name} works ${this.hours || 'nothing'} hours on ${this.project}`;
  }
}

let person = new TimeTracker();
person.addHours = 2; // 标准 setter
person.hours = 4;    // 绕过 setter 进行设置
person.timeSheet;

可以看到,在类中没有任何措施可以防止在不调用 setter 的情况下更改属性。

而私有类字段将使用哈希#前缀定义,从上面的示例中,可以修改它以包含私有类字段,以防止在类方法之外更改属性:

class TimeTracker {
  name = 'zhangsan';
  project = 'blog';
  #hours = 0;  // 私有类字段

  set addHours(hour) {
    this.#hours += hour;
  }

  get timeSheet() {
    return `${this.name} works ${this.#hours || 'nothing'} hours on ${this.project}`;
  }
}

let person = new TimeTracker();
person.addHours = 4; // 标准 setter
person.timeSheet     // zhangsan works 4 hours on blog

//当尝试在 setter 方法之外修改私有类字段时,就会报错(但是自己实践的话并不会出现这个错误,环境是最新chrome,具体如下图,会出现一个公共属性hours):
person.hours = 4 // Error Private field '#hours' must be declared in an enclosing class

image.png

还可以将方法或 getter/setter 设为私有,只需要给这些方法名称前面加#即可:

class TimeTracker {
  name = 'zhangsan';
  project = 'blog';
  #hours = 0;   // 私有类字段

  set #addHours(hour) {
    this.#hours += hour;
  }

  get #timeSheet() {
    return `${this.name} works ${this.#hours || 'nothing'} hours on ${this.project}`;
  }

  constructor(hours) {
    this.#addHours = hours;
    console.log(this.#timeSheet);
  }
}

let person = new TimeTracker(4); // zhangsan works 4 hours on blog

3.实现一个类似instanceof的功能

function instance_of(L, R) { // L 表示实例,R 表示构造函数
    var O = R.prototype;
  	//获取到L的实例原型
    L = Object.getPrototypeOf(L); 
    while (true) {  
        if (L === null)      
             return false;   
        if (O === L)
             return true;   
        L = L.__proto__;  
    }
}
const R = function () {}
const l = new R
const raw = l instanceof R
const rawMock = instance_of(l, R)
console.log(rawMock, raw)

4.实现对于引用类型的比较

const isEqual = (o1, o2) =>
  [...new Set([...Object.keys(o1), Object.keys(o2)])].every(k => {
    if (o1[k] && o2[k] && typeof o1[k] === 'object' && typeof o2[k] === 'object')
      return isEqual(o1[k], o2[k])
    if (o1[k] !== o2[k]) console.log('值不相同的key:', k)
    return o1[k] === o2[k]
  })