# call

  • 功能:将函数 this 指向更改为第一个传入的形参对象,并调用函数本身
  • 参数:
    • thisArg:可选的。在 function 函数运行时使用的 this 值。请注意, this 可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 nullundefined 时会自动替换为指向全局对象,原始值会被包装。
    • arg1, arg2, ...:可选的。指定的参数列表。
  • 返回值:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

# ES5 写法

Function.prototype.myCall = function(){
    // 拿到传入的第一个参数
    var thisArg = [].shift.apply(arguments);
    // 转换 arguments 为数组
    var args = [].slice.apply(arguments);
    var fn = 'Symbol';
    thisArg[fn] = this;
    var res = thisArg[fn].apply(args);
    delete thisArg[fn];
    return res;
};

# ES6 写法

// 将方法定义在 Fuction 的 prototype 上,这样任何一个函数对象都可以使用该方法
Function.prototype.myCall = function(thisArg,...args){
    // 判断第一个传入的形参是否为空
    if(thisArg === null || thisArg === undefined){
        thisArg = thisArg || window;
    };
    // 保存调用该方法的 this,该 this 指向的也就是调用 myCall 方法的那个函数对象本身
    const fn = Symbol(0); // 用 Symbol 做唯一标识符,防止与源函数对象上的属性名冲突而产生覆盖
    thisArg[fn] = this;
    // 调用源函数
    const res = thisArg[fn](...args);
    // 清理属性名,使原来传入的对象其恢复原样
    delete thisArg[fn];
    // 返回改变 this 后源函数调用结果
    return res;
};

# apply

  • 功能:同 call,将函数 this 指向更改为第一个传入的形参对象,并调用函数本身

  • 参数:

    • thisArg:可选的。在 func 函数运行时使用的 this 值。
    • argsArray:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null undefined ,则表示不需要传入任何参数。
  • 返回值:使用调用者提供的 this 值和参数调用该函数的返回值。若该方法没有返回值,则返回 undefined

# ES5 写法

Function.prototype.myApply = function(){
    // 拿到传入的第一个参数
    var thisArg = [].shift.call(arguments);
    // 转换 arguments 为数组
    var args = [].slice.call(arguments);
    var fn = 'Symbol';
    thisArg[fn] = this;
    var res = thisArg[fn].apply(args);
    delete thisArg[fn];
    return res;
};

# ES6 写法

// 步骤基本和 call 一样,唯一的区别就是第二个参数是给源函数使用的参数数组
Function.prototype.myApply = function(thisArg,argsArray){
    if(thisArg === null || thisArg === undefined){
        thisArg = thisArg || window;
    }
    const fn = Symbol(0);
    thisArg[fn] = this;
    // 调用源函数,将参数组数展开
    const res = thisArg[fn](...argsArray);
    delete thisArg[fn];
    return res;
}

# bind

  • 功能:将函数 this 指向更改为第一个传入的形参对象,而其余参数将作为返回的新函数的参数,供调用时使用。
  • 参数:
    • thisArg:调用绑定函数时作为 this 参数传递给目标函数的值。
    • arg1, arg2, ...:当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
  • 返回值:返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。

# ES5 写法

Function.prototype.myBind = function () {
    const arr = [].slice.apply(this,arguments)
    const thisArg = arr.shift();
    const fn = this;
    return function(){
        const arr2 = [].slice.apply(this,arguments)
        return fn.apply(thisArg,arr.concat(arr2))
    }
};

# ES6 写法

Function.prototype.myBind = function(thisArg,...args1){
    if(thisArg === null || thisArg === undefined){
        thisArg = thisArg || window;
    };
    const fn = this;
    return function(...args2) {
        return fn.apply(thisArg,args1.concat(args2));
    };
}