美文网首页
手写 call、apply 及 bind

手写 call、apply 及 bind

作者: McDu | 来源:发表于2021-03-11 11:12 被阅读0次
  1. call
Function.prototype.myCall = function(context) {
    if(typeof this !== 'function') {
        return;
    }

    // context 不传入或为 null,可指向 window
    context = Object(context) || window;
    context.fn = this;

    const args = [...arguments].slice(1);
    const result = context.fn(...args);
    
    delete context.fn;
    return result;
}
  1. apply
Function.prototype.myApply = function(context, arr) {
    context = Object(context) || window;
    context.fn = this;
  
    let result;
    if(!arr) {
        result = context.fn();
    } else {
        result = context.fn(...arguments[1]);
    }

    delete context.fn;

    return result;
}
  1. bind
    bind() 方法会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数。
Function.prototype.myBind = function(context) {
    const self = this;
    
     // 获取 bind 函数从第二个参数到最后一个参数
    const args = [...arguments].slice(1);
    
    return function() {
        return self.apply(context, args.concat(...arguments))
    }
}

bind 还有一个特点,就是 一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
也就是说当 bind 返回的函数作为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效。

Function.prototype.myBind2 = function(context) {
    const self = this;
    
     // 获取 bind 函数从第二个参数到最后一个参数
    const args = [...arguments].slice(1);
    
    return function Fn() {
        // 可以当构造函数调用
        if(this instanceof Fn) {
            return new self(...args, ...arguments)
        }

        return self.apply(context, args.concat(...arguments))
    }
}

分析:
bind 返回一个函数,函数有两种调用方式,一是直接调用,二是用 new 的方式当做构造函数调用

  1. 直接调用:因为 bind可以这样使用:fn.bind(obj, 1, 2)(3, 4) 所以需要把参数拼接即 args.concat(...arguments)
  2. new 调用:需忽略 this

相关文章

网友评论

      本文标题:手写 call、apply 及 bind

      本文链接:https://www.haomeiwen.com/subject/vsawqltx.html