携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
1 Call
js中call方法我们都知道是用来改变this指向并且调用函数的,
首先了解Function.call(context,argumnets),context是指的我们要改变到的this指向,agruments是我们穿的的参数
其实具体的实现流程就是一下几步
1:创建一个对象obj如果有context的传入obj=Object(context),没有的话obj=window
2:创建一个独一无二的key值
3:obj[key]=this(这时的this就是fn.call()的fn的函数体)
4:调用fn
5:删除obj的key
6:返回结果
代码实现为
本质思想就是创建一个对象 把fn当作对象的一个属性调用这时this指向就会指向该对象
Function.prototype.myCall=function(context,...arguments){
const obj=context===undefined?window:Object(context)
const key=Symbol()
obj[key]=this
let result=obj[key](...arguments)
delete obj[key]
return result
}
2 New
我们常用 new 构造函数来创建一个对象,那么new内部具体怎么实现的呢,
也是分为一下几步
1:创建新的对象
2:让该对象的__proto__属性指向构造函数的prototype
3:调用构造函数
4:如果构造器没有手动返回对象,则返回第一步的对象
function myNew(fn,...arg){
let obj={}
obj.__proto__=fn.prototype
let result=fn.call(obj,...arg)
return typeof result === 'object'?result:obj;
}
3 promise(阉割版)和promise.all
// 设置三个状态
const PENDING='pending'
const FULFILLED="fulfilled"
const REJECT='reject'
class MyPromise{
constructor(executor){
// 函数立即执行
executor(this.reslove,this.reject)
}
state=PENDING
value=null
reason=null
resolveTemp=null
rejectTemp=null
// 成功返回
reslove(value){
this.state=FULFILLED
this.value=value
this.resolveTemp && this.resolveTemp(value)
}
// 失败返回
reject(reason){
this.state=REJECT
this.reason=reason
this.rejectTemp && this.rejectTemp(reason)
}
// then
then(resovleCallBack,rejectCallBack){
if(this.state=FULFILLED){
resovleCallBack(this.value)
}else if(this.state===REJECT){
rejectCallBack(value)
}else if(this.state===PENDING){
this.resolveTemp=resovleCallBack
this.rejectTemp=rejectCallBack
}
}
}
// promise.all
// 设置一个count值每个promise成功返回count++ 直到count值为arr.length时成功返回,否则失败一个直接reject
function myPromiseAll(arr){
return new Promise((resovle,reject)=>{
let length=arr.length
if(arr.length===0){
resovle(new Promise.resolve(arr))
}
let count=0
let result=[]
for(var i=0;i<arr.length;i++){
arr[i].then(res=>{
count++
result.push(res)
if(count===length){
resovle(result)
}
}).catch(err=>{reject(err)})
}
})
}
// promise race
// 只要一个promise成功返回直接resolve
function myPromiseRace(arr){
return new Promise((resolve,rejcet)=>{
for(let i=0;i<arr.length;i++){
arr[i].then(res=>{
resolve(res)
}).catch(err=>{rejcet(err)})
}
})
}