美文网首页
apply、call与bind方法修改this指向

apply、call与bind方法修改this指向

作者: GoFzy | 来源:发表于2019-03-08 20:40 被阅读0次

    以下都是在非严格模式下进行讨论

    一、apply与call

    function f1(x,y){
      console.log("结果是:" + (x + y) + this); 
    }
    f1(10,20); //30[object Window]    此时this指向window对象,很好理解
    f1.apply(null,[10,20]);  //30[object Window] 
    f1.call(null,10,20);  //30[object Window] 
    

      apply和call方法中如果第一个参数传入的是null,那么调用该方法的函数对象中this仍默认的指向。两个作用一致,只是传参形式不同。

    function f1(x,y){
      console.log("结果是:" + (x + y) + this); 
    }
    var obj = {
      age: 10,
      sex: "male"
    }
    f1.apply(obj,[10,20]);  //30[object Object] 
    f1.call(obj,10,20);  //30[object Object] 
    console.dir(obj); // obj中不存在f1方法
    

      第一个参数传入对象后,可以修改this指向,此时指向传入的对象。需要注意的是apply和call只是”临时借用“obj对象,并不会将方法添加到该对象中。

    二、扩展问题:apply和call到底属于谁的方法?

        function f(){
            console.log(this+'我被调用了');
        }
        f.apply();
        f.call();
        console.dir(f);
    
    输出结果

      首先我们知道f既是函数也是对象,上段代码中显示f能够调用apply和call方法,那么f中是否含有apply和call呢?所以我用console.dir查看了下f函数的结构:


    f函数对象结构

      发现事情并不简单,两个方法并不是直接存在与f函数对象中。那就往原型对象中查找,函数对象f是谁的实例对象呢?Function!

       console.log(f.__proto__ == Function.prototype) //true
      console.dir(Function);
    
    Function对象

      现在结果就很明了了,所有函数都是Function的实例对象,而apply和call都属于Function的原型对象(prototype)之中。

    三、bind方法

    function f1(x,y){
      console.log("结果是:" + (x + y) + this); 
    }
    f1.bind(); //此时函数并没有执行,这里只是单纯的复制了一份
    var ff = f1.bind(); 
    ff(10,20); //30[object Object]  此时没有传入指向对象,故保持默认
    var fz = f1.bind(null,10,20);
    fz(); //30[object Object]  与ff结果一样,只不过是第二种写法,参数两处都可以传入
    var obj = {
      age: 10,
      sex: "male"
    }
    var fzy = f1.bind(obj,10,20);
    fzy(); //30[object Object] 
    

      总结一下:
      ①bind方法是复制的意思,即复制一份新函数,参数可以在复制的时候传入,也可以在复制之后调用时传入
      ②call和apply是调用的时候改变this指向--适用于直接调用
      ③bind是复制该函数 的时候改变了this 的指向,适合作为参数传递

    相关文章

      网友评论

          本文标题:apply、call与bind方法修改this指向

          本文链接:https://www.haomeiwen.com/subject/hzedpqtx.html