2024-8-4 打卡第六天 学习视频链接
使用class手写一个Promise
- 由于
setTimeout
是异步的,当then
方法被调用时,Promise
可能还没有被解决或拒绝。因此,需要在Promise
状态改变时执行then
方法中提供的回调函数。这通常通过维护一个回调函数队列来实现 - 由于 Promise 通常用于处理异步操作(如网络请求、文件操作或定时器回调),当 Promise 被创建时,它的最终状态(解决或拒绝)可能尚未确定。因此,then 方法中提供的回调函数不能立即执行;它们必须等待 Promise 的状态发生变化。当 Promise 的状态从 "pending" 变为 "fulfilled" 或 "rejected" 时,存储在相应队列中的回调函数将被执行。这是通过检查 Promise 的当前状态并在状态变化时遍历并调用这些回调函数来实现的。
<script>
class myPromise{
constructor(executer){
this.status = "pending";
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
let resolve = (value) => {
if(this.status === "pending"){
this.status = "fulfilled";
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn(value));
}
}
let reject = (reason) => {
if(this.status === "pending"){
this.status = "rejected";
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(reason));
}
}
try {
executer(resolve,reject)
}catch(e){
reject(e);
}
}
then(onFulfilled,onRejected){
if(this.status === "resolve"){
onFulfilled(this.value);
}
if(this.status === "reject"){
onRejected(this.value);
}
else {
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}
}
}
let pro = new myPromise((resolve,reject) => {
setTimeout(() => {
reject("失败了");
},1000)
});
pro.then(
value => console.log(value),
reason => console.log(reason)
)
</script>
使用Set去重
- Set 对象的构造函数期望的是一个可迭代对象(如数组),然后使用展开操作符从 Set 中获取去重后的数组。new Set(arr) 创建了一个包含数组 arr 中所有唯一元素的 Set 对象。然后,使用展开操作符 ... 将 Set 对象转换为一个新的数组 item,该数组包含了原始数组中的所有唯一元素
<script>
let arr = [1,2,3,3,3,4,4];
let item = [...new Set(arr)];
console.log(item);
</script>
将for循环改成for of
- for of是es6新增的,之前有的是for in。
- for...of:用于遍历可迭代对象(如数组、字符串、Map、Set、TypedArray、arguments 对象等)的值。它直接访问可迭代对象的值,而不是索引。for...in:用于遍历对象的可枚举属性(包括原型链上的可枚举属性,除非使用 hasOwnProperty() 方法进行过滤)。它遍历的是对象的键(key),而不是值
- for...of:不会遍历原型链上的属性,因为它只针对可迭代对象。for...in:会遍历对象自身及其原型链上的所有可枚举属性。因此,它可能会遍历到意料之外的属性。即在原型链上添加数据也会遍历出来
let arr = [1,2,3,3,3,4,4];
let sum = 0;
for(let i = 0; i < arr.length; i++){
sum+= arr[i];
}
// 同等为
for(value of arr){
sum+=value;
}
console.log(sum)
WeakSet和WeakMap的区别
WeakSet和Set区别
- WeakSet成员只能是对象,不能是其他类型的值
- WeakSet对象都是弱引用(如果其他对象都不再使用该对象,垃圾回收机制会自动回收)不可遍历,没有size属性
- WeakSet 用处:存储dom节点
Map
- 对象的数据结构 键值对集合,键:多类型
- 可以接受数组作为参数 键值对数组
- Map的键跟内存地址进行绑定,内存地址不一样视为两个键
- 如果是简单类型值,值相等会视为一个键
- Map的遍历顺序就是插入顺序
WeakMap和Map的区别
- WeakMap只接受对象作为键值
- 键名是对象的弱引用
- WeakMap没有key,values,entries,size等
-
无法清空clear
- WeakMap只有四种方法:get set has delete
- 防止内存泄漏
箭头函数和普通函数的区别
- 比普通函数语法简介
- 箭头函数没有perototype属性,没有this
- 箭头函数的this指向外层作用域普通函数的this,不变
- call apply bind都不能改变箭头函数的this指向
- 不能定义构造函数,即不能使用new
- 箭头函数没有arguments,使用rest代替
- .rest参数即..是一个展开运算符,但在参数列表中,它有一个不同的作用:它表示该函数将接收一个不定数量的参数,并将这些参数收集到一个名为b的数组中
<script>
function A(a){
console.log(arguments)
}
A(1,2,3,4);
// rest参数
let B = (...b) => {
console.log(b)
}
B(1,2,3);
</script>
- 箭头函数不能用做Generator,也不能使用yield
模块化开发
- export导出模块,import输入模块(加载模块)
- 一个模块就是一个独立的文件,文件内部的所有变量外部无法获取,需要外部获取的话要用export导出
- export default 命令为模块默认导出,只能有一个默认导出所以只能使用一次
<script>
export var name = "encoder"
var.name = "encode"
var.age = 12
export {name,age}
function fn1(){}
function fn2(){}
export {fn1 as checkName,fn2 as checkAge}
</script>