其他分享
首页 > 其他分享> > 温故知新(九二)实现 call,bind,apply

温故知新(九二)实现 call,bind,apply

作者:互联网

手动实现 call,bind,apply

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

答案:

call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组

Function.prototype.myCall = function(context,...args){
    //谁调用的call,谁就是这个this,必须是一个function,比如:fn.call(obj,1,2,3),这时候fn就是我们拿到的this
    if(typeof this !== 'function'){
        throw new TypeError('not function!');
    }
    const fn = this;
    let result = null;

    context = context || window;
    //把fn 赋值给传入的要绑定的this对象,所以fn里面的fn就变成了 上面传入的context
    context.fn = fn;
    //执行fn
    result = context.fn(...args);
    //删除context.fn属性,解除引用
    delete context.fn;
    //返回执行结果
    return result;
}

bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。

使用apply:

if (!Function.prototype.bind) (function(){
  var slice = Array.prototype.slice;
  Function.prototype.bind = function() {
    var thatFunc = this, thatArg = arguments[0];
    var args = slice.call(arguments, 1);
    if (typeof thatFunc !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - ' +
             'what is trying to be bound is not callable');
    }
    return function(){
      var funcArgs = args.concat(slice.call(arguments))
      return thatFunc.apply(thatArg, funcArgs);
    };
  };
})();

思路

1.拷贝源函数:

2.返回拷贝的函数

3.调用拷贝的函数:

 

Function.prototype.myBind = function (objThis, ...params) {
    const thisFn = this; // 存储源函数以及上方的params(函数参数)
    // 对返回的函数 secondParams 二次传参
    let fToBind = function (...secondParams) {
        console.log('secondParams',secondParams,...secondParams)
        const isNew = this instanceof fToBind // this是否是fToBind的实例 也就是返回的fToBind是否通过new调用
        const context = isNew ? this : Object(objThis) // new调用就绑定到this上,否则就绑定到传入的objThis上
        return thisFn.call(context, ...params, ...secondParams); // 用call调用源函数绑定this的指向并传递参数,返回执行结果
    };
    fToBind.prototype = Object.create(thisFn.prototype); // 复制源函数的prototype给fToBind
    return fToBind; // 返回拷贝的函数
};

 

 

apply() 方法调用一个具有给定 this 值的函数,以及以一个数组(或类数组对象)的形式提供的参数。


Function.prototype.myApply = function(context,argArr){
    if(typeof this !== 'function'){
        throw new TypeError('not function');
    }
    if(argArr && !Array.isArray(argArr)){
        throw new TypeError('the second argument need an array');
    }
    const fn = this;
    let result = null;

    context = context || window;
    argArr = argArr || [];
    context.fn = fn;
    result = context.fn(...argArr);
    delete context.fn;

    return result;
}

 

标签:function,函数,温故知新,call,context,九二,prototype,fn
来源: https://blog.csdn.net/MFWSCQ/article/details/108443151