前端高级javascript进阶之call、apply原理

256 阅读1分钟

两年多的前端小菜鸟一枚,之前都是看别人写的文章,一直没有产出属于自己脑子里的东西,从今日便开始自己的写作之旅,不喜勿喷(想写出像别的大佬一样的文采,可惜没有)

call和apply的不同只是在于传的第二个参数不同而已,call的第二个参数是一个一个的,apply传的参数是数组。

一、call的实现原理

  • call的特点
  1.  改变当前函数this指向
  2.  执行当前函数
  • call的原理

       函数都可以调用call,说明call是函数原型上的方法,所有的实例都可以调用,即Function.prototype.call;其次,若第一个参数没有传进来,在全局环境下,那么默认this指向window(浏览器)/global(node),传入call的第一个参数是this指向的对象,根据obj.foo(),foo()中的this指向obj,因此我们可以这样调用函数thisArgs.func(...args),所以相应的func中的this就指向了thisArgs,然后返回执行结果。

Function.prototype._call = function() {
    let [thisArgs, ...args] = arguments;

    if(!thisArgs) {
        thisArgs = typeof window === 'undefined' ? global : window;
    }
    
    thisArgs.func = this; //核心
    
    let result = thisArgs.func(...args); //执行函数,执行this();

    delete thisArgs.func;
    return result;
}

let obj = {
    name: 'wf'
}

function fn (age, name) {
    console.log(this);
    console.log(age, name)
}

fn._call(obj, 26, 'hello') // wf 26 hello

二、apply的实现原理

  • 和call的实现原理一样,只是处理参数不同而已

    Function.prototype._apply = function() { let [thisArgs, args] = arguments; let result; if(!thisArgs) { thisArgs = typeof window == 'undefined' ? global : window; } thisArgs.func = this; if(!args) { result = thisArgs.func(); }else { result = thisArgs.func(...args) } delete thisArgs.func; return result }

    let obj = { name: 'wf' }

    function (age, name) { console.log(this) console.log(age, name) }

    fn._apply(obj, [26, 'hello']) //wf 26 hello

下集--实现bind原理。