js系列之实现call, apply, bind函数

博客介绍了bind、call和apply的作用及区别。它们都能改变上下文this指向,call和apply直接用于函数,bind绑定this后返回闭包函数。call可传多个参数,apply第二个参数为数组。bind支持柯里化传参,但作构造函数使用时会出错,还需解决原型丢失问题。

bind 和 call/apply 一样,都是用来改变上下文 this 指向的,不同的是,call/apply 是直接使用在函数上,而 bind 绑定 this 后返回一个函数(闭包) call和apply的唯一区别是call的除了第一个参数是绑定上下文,可以传多个参数,apply的第一个参数是绑定上下文,第二个参数是一个数组 call

Function.prototype.myCall = function(context) {
    // 处理第一个参数传null或者undfined,这时将上下文绑定到window对象上
    context = context || window;
    context._fn = this;
    let args = [...arguments].slice(1);
    let result = context._fn(...args);
    delete context._fn;
    return result;
}
复制代码

apply

    Function.prototype.myApply = function(context) {
    context = context || window;
    context._fn = this;
    let args = [...arguments].slice(1); // 第二个参数是数组
    let result = context._fn(...args);
    delete context._fn;
    return result;
}
复制代码

bind

  1. 函数调用,改变this
  2. 返回一个绑定this的函数
  3. 接收多个参数
  4. 支持柯里化形式传参 fn(1)(2)
Function.prototype.myBind = function(context) {
    let self = this;
    let args = [...arguments].slice(1);
    return function() {
        let newArgs = [...arguments];
        return self.apply(context, args.concat(newArgs))
    }
}
复制代码

但是作为构造函数试用的时候会出错,构造函数的this绑定在实例上,除此之外,还需要解决原型丢失的问题

Function.prototype.myBind = function(context) {
    let self = this;
    let args = [...arguments].slice(1);
    var bound = function() {
        let newArgs = [...arguments];
        // 作为构造函数使用
        if(this instanceof bound) {
            return self.apply(this, args.concat(newArgs))
        } else {
            return self.apply(context, args.concat(newArgs))
        }
    }
    // 维护原型关系
    if(this.prototype) {
        bound.prototype = this.prototype;
    }
    return bound;
}
复制代码

转载于:https://juejin.im/post/5cd24831e51d456e8b07de1d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值