手写call、apply、bind

246 阅读1分钟

1.手写call

call方法在Function原型对象上,我们自己封装时也需将其挂载到Function原型对象上

// 1.call
Function.prototype.myCall = function(ctx, ...args){
    ctx.fn = this, // this指向mycall的调用函数,同时为ctx添加了一个方法fn(即this指向mycall的调用函数)
    ctx.fn(...args), //通过ctx执行fn,此时fn中this指向ctx
    delete ctx.fn  //删除ctx上的fn方法
}
function show1(...args){
    console.log(...args);
    console.log(this.name);
}
show1.myCall({name:'zhangshan'}, 'zhan', 'li', 'wang')

2.手写apply

写apply的方法与call相似,唯一不同就是传参方式不同,call第二个参数是数据列表,而apply是一个数组

// 2.call
Function.prototype.myApply = function(ctx, args = []){
    ctx.fn = this,
    ctx.fn(...args),
    delete ctx.fn
}
function show2(...args){
    console.log(...args);
    console.log(this.name);
}
show2.myApply({name:'lisi'}, ['z', 'l', 'w'])

3.手写bind

bind与上面写法类似,不同之处在于bind需手动调用,代码如下

// 3.bind
Function.prototype.myBind = function(ctx, ...args1){
    return (...args2) => {   //此处需返回一个函数
        ctx.fn = this,
        ctx.fn(...args1.concat(args2)) //合并参数
        delete ctx.fn
    }
}
function show3(...args){
    console.log(...args);
    console.log(this.name);
}
show3.myBind({name:'wangwu'},'zh', 'li', 'wang')('lao')

4.总结

手写call、apply、bind的关键代码是要理解ctx.fn = this这步至关重要的操作