js手写bind、call、apply

127 阅读1分钟

bind

1、bind会改变this 的指向为第一个参数 2、返回一个函数

Function.prototype.bind1 = function() {
    //将参数解析未数组
    const args = Array.prototype.slice.call(arguments);
    // 获取this(取出数组的第一项,数组剩余的就是传递参数)
    const t = arg.shift(); // 获取第一个参数
    const self = this; // 当前函数的this
    // 返回一个函数
    return function() {
        // 执行原函数,并返回结果
        return self.apply(t, args);
    }
}

call

call的特点 1、可以改变我们当前函数的this指向。 2、还会让当前的函数执行 3、每一个方法上面都会有一个call和applay方法,这是一个方法原型上的方法

Function.prototype.ownCall = function(context){ // 传的就是一个上下文,如果没有参数就是window
    context = context ? Object(context) : window;
    context.fn = this; 

    // 拿到参数
    let args = [];
    // 从1开始循环的原因是,第一个是我们的上下文,后面的才是我们的参数
    for(let i = 1; i < arguments.length; i++) { 
        args.push('arguments['+i+']'); // 这样传进来的就是 // ['','',''];
    }

    // 利用数组的tostring方法
    let r = eval('context.fn('+args+')') // eval是可以让字符串执行

    delete context.fn;
    return r
    
}

function mycall1(){
    console.log(1, this); 
}

function mycall2(){
    console.log(2, this); 
}

mycall1.ownCall(mycall2); // 1  // this指向了mycall2,并且执行mycall1
mycall1.ownCall.ownCall.ownCall(mycall2) // 2  // 执行的是mycall2

apply

1、apply和call的方法的区别是apply的第二个参数传的是一个数组 2、他们的第一个参数都是this指向

Function.prototype.ownApplay = function(context, args){ // 传的就是一个上下文,如果没有参数就是window
    context = context ? Object(context) : window;
    context.fn = this; 

    // 拿到参数 就是一个数组
    if(!args) return context.fn();

    // 利用数组的tostring方法
    let r = eval('context.fn('+args+')') // eval是可以让字符串执行

    delete context.fn;
    return r
    
}

function mycall1(){
    console.log(1, this); 
}

function mycall2(){
    console.log(2, this); 
}

mycall1.ownApplay('hello', [1,2,3,4])