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
还可以将方法或 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]
})