手动实现 call、apply、bind

手动实现 call、apply、bind

改变 this的指向,就是将函数fn放入传入的context中,然后执行context[fn](),此时的fn中的this就变成了context,在函数执行完毕之后,需删除context中的fn

call

  1. 判断当前 this 是否为函数,防止 Function.prototype.myCall()直接调用
  2. context为可选参数,如果不传的话默认上下文为 window
  3. 为 context 创建一个 Symbol(保证不会重名)属性,将当前函数赋值给这个属性
  4. 处理参数,传入第一个参数后的其余参数
  5. 调用函数后即删除该 Symbol 属性
Function.prototype.myCall = function(context = window, ...args) {
    if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
    }
    context = context || window;
    const fn = Symbol();
    context[fn] = this;
    const result = context[fn](...args);
    delete context[fn];
    return result;
};

apply

apply 实现类似 call,参数为数组

Function.prototype.myApply = function(context = window, args) {
    if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
    }
    const fn = Symbol();
    context[fn] = this;
    let result;
    if (Array.isArray(args)) {
        result = context[fn](...args);
    } else {
        result = context[fn]();
    }
    delete context[fn];
    return result;
};

bind

因为 bind()返回一个方法需手动执行,因此利用闭包实现。

Function.prototype.myBind = function(context, ...args1) {
    if (this === Function.prototype) {
        throw new TypeError('Error');
    }
    const _this = this;
    return function F(...args2) {
        // 判断是否用于构造函数
        if (this instanceof F) {
            return new _this(...args1, ...args2);
        }
        return _this.apply(context, args1.concat(args2));
    };
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值