call、apply和bind的区别及如何手写

三者的相同点:都是用来改变this的指向

1.call()和apply()的区别:

都是调用一个对象的一个方法,用另一个对象替换当前对象(功能相同)

B.call(A, args1,args2);即A对象调用B对象的方法
F.apply(G, arguments);即G对象应用F对象的方法

相同点:第一个参数是this要指向的对象,当第一个参数为null、undefined时,默认指向window;

不同点:apply()第二个参数是数组,call()是参数列表

2.与bind()的区别:

call和apply在改变方法的this指向时,会同时执行方法;而bind不会执行方法,而是返回改变this指向后的新方法

var x = "window_x";
var obj = {
    x : "obj_x",
    fn : function(y){
        console.log(this.x + " ; " + y);
    }
}
obj.fn(1);  //obj_x ; 1
var fn = obj.fn;
fn(1);  //window_x ; 1
fn.call(obj,1);  //obj_x ; 1
fn.apply(obj,[1]);  //obj_x ; 1
fn.bind(obj,1);  //返回fn方法:f (y){console.log(this.x + " ; " + y);}
var bfn = fn.bind(obj);
bfn(1); //obj_x ; 1

执行结果:
在这里插入图片描述

3.常见用法:

3.1 利用apply()求最大值
var arr =[2,6,8,3,4,9,7,23,56,889]; 
console.log(Math.max.apply(null,arr))
console.log(Math.max.apply(arr,arr)) 
//第一个arr表示让arr借用max这个方法,第二个arr表示传给max的数据
//apply()所执行的操作:1.执行Math.max(1,2,3,5,4) 2.把内部的this改成arr

4.手写call():

    Function.prototype.newcall = function(par){
        //有参用参,无参指向window
        par = par || window;
        //添加一个属性 赋值给this
        par.fn = this;
        //arguments [function,参数] 截取参数 为从funciton后的形成新的数组[par];
        var arg = [...arguments].slice(1);
        //将数组作为入参给定义的 调用方法 ...arg将arg转为用逗号分隔的参数序列
        var result =  par.fn(...arg);
        //原来par是没有fn的,删除掉,不影响继承结构
        delete  par.fn;
        return result;
    };

5.手写apply():

// 思路:将要改变this指向的方法挂到目标this上执行并返回
Function.prototype.myapply = function (ctx) {
    ctx = ctx||window;
    ctx.fn = this;
    var result;
    //arguments 此时为 [fn ctx(),[参数];
    if(arguments[1]){
            //[参数]对应apply传的数组
        result =ctx.fn(...arguments[1]);
    }else{
        result =ctx.fn();
    }
    delete ctx.fn;
    return result;
}

验证方法是否生效:

 function add(a,b){
        return a+b;
    }
    function sub(a,b){
        return a - b;
    }

console.log(add.newcall(sub,10,15));

console.log(add.myapply(sub,[10,20]));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值