call、apply、bind 的用法和区别

call、apply、bind 的用法和区别

首先:call、apply、bind的作用是改变函数运行时的this的指向

var zr = {
        a: 1,
        fn: function () {
            console.log(this.a); //1
        }
    }
    zr.fn();
    //相当于zr.fn.call(zr)或者zr.fn.apply(zr);
var zr = {
        a: 1,
        b: {
            a: 2,
            fn: function () {
                console.log(this.a);
            }
        }
    }
    //this指向zr对象中的b,所以打印的是this上一级对象,所以输出2
    zr.b.fn(); //2
    //此处使用call或者apply函数 把this从指向b改变为指向zr  
    console.log(zr.b.fn.call(zr)) //1
    console.log(zr.b.fn.apply(zr)) //1
    //也就相当于是变成了
    var zr = {
        a: 1,
        fn: function () {
            console.log(this.a); //1
        }
    }
//由于普通函数(没有父级对象)没有任何调用,所以其this就指向window;
function zr() {
        var username = "睿睿";
        console.log(this.username); //undefined
        console.log(this); //Window
    }
    zr();
    //相当于zr.call(undefined)

所以setTimeout作为一个普通的回调函数,其this是指向window;这就是setTimeout()丢失this的原因;所以在使用setTimeout()的时候:var _this=this;

接下来进入正题

call()可以传n个参数,但是第一个参数是this将要指向的对象 当第一个参数为null或者undefined的时候,this默认指向window;之后的参数相当于普通传参一样自定义使用;

apply()只可以传俩个参数,第一个参数和call()的第一个参数一样,是this将要指向的对象;当第一个参数为null或者undefined的时候,this默认指向window;;第二个参数是一个数组,相当于把call()除第一个参数外的所有参数放到一个数组中;

var zr = {
        a: 1,
        b: {
            a: 2,
            c: {
                a: 3,
                fn: function (x , y) {
                    console.log(this.a);
                    console.log(x+y);
                }
            }

        }
    }
    //此处使用call或者apply函数 把this从指向c改变为指向b 
    zr.b.c.fn.call(zr.b ,1 , 2) //2     3
    zr.b.c.fn.apply(zr.b ,[1 , 2] ) //2     3
     //此处使用call或者apply函数 把this从指向c改变为指向zr
    zr.b.c.fn.call(zr ,1 , 2) //1     3
    zr.b.c.fn.apply(zr ,[1 , 2] ) //1     3
     //此处使用call或者apply函数 第一个参数传null,this默认指向window
    zr.b.c.fn.call(null ,1 , 2) //undefined  3
    zr.b.c.fn.apply(null ,[1 , 2] ) //undefined    3

其实apply() 和 call() 的用法基本上相同, 唯一的差别就是:当函数需要传递>1个变量时, apply() 可以接受一个数组作为参数, call() 必须接受>1个的单独变量。

bind()的传参方式和call()很相似,第一个参数是this将要指向的对象,第一个传null得话不改变this指向,并且可以在后续的调用中去传入参数

//后续的调用中去传入参数
function zr(a, b, c) {
        return a * b * c;
    }

    var fn = zr.bind(null, 2);

    //相当于
    //function fn(2, b, c) {
        //return 2 * b * c;
    //}
    
    console.log(fn(3, 4));//24
    
    //相当于
    //function fn(2, 3, 4) {
        //return 2 * 3 * 4;
    //}


    //bind()返回的一个改变了 this 之后的新函数;原函数zr中的this并没有改变;
    var obj = {
        username:'睿睿'
    }
    function zr () {
        console.log(this.username)
    }
    var bindfn =zr.bind(obj)
    bindfn()//睿睿
    //zr () {
        //console.log(this.username)
    //}

猜你喜欢

转载自blog.csdn.net/a791226606/article/details/106252823