zoukankan      html  css  js  c++  java
  • js call回调的this指向问题

    function fn1(){
       console.log(1);
    }
    function fn2(){
        console.log(2);
    }
    
    fn1.call(fn2);     //输出 1
     
    fn1.call.call(fn2);  //输出 2
    对于 fn1.call(fn2);我能够理解,这段代码仅仅 使得 fn1对象的this指向了fn2;但是最终不影响fn1函数的执行。因为fn1中不包含对this的操作。
    

      A.call( B,x,y ):就是把A的函数放到B中运行,x 和 y 是A方法的参数。

    面试题:
    function fn(a,b){
        console.log(this);
        console.log(a);
        console.log(a+b);
    }
    fn.call(1);
    fn.call.call(fn);
    fn.call.call.call(fn,1,2);
    fn.call.call.call.call(fn,1,2,3);
    
    答案:
    fn.call(1);  // 1,undefined,NaN
    fn.call.call(fn);   // fn,undefined,NaN 
    fn.call.call.call(fn,1,2);  //  1,2,NaN
    fn.call.call.call.call(fn,1,2,3);  //  1,2,5
    
    深层解题思路:
    fn.call(1);call的第一个参数改变call前面函数里的关键字this所以输出1;后面没有参数所以a,b为undefined,相加结果为NaN;
    fn.call.call(fn);这一块是个难点,不过也很好理解! fn.call 找到Function.prototype上的call方法(这也是一个函数,也是函数类
                     的一个实例,也可以继续调用call/apply等方法)我们可以把fn.call看成一个函数 A 那么接下就等于A.call(fn),这
                     里执行call方法,把 A 中的关键字this修改为函数 fn ,然后再把函数 A(fn.call) 执行;
    fn.call.call.call(fn,1,2);通过上一条的原型链的方法我们可以把 fn.call.call.call 看成 A(fn.call.call).call 执行,此时括
                     里的参数 fn 已经作为函数执行了,所以就成了 A.call(1,2) 执行!1作为第一个参数改变 call 前面函数里的this,
                     后面的参数作为实参传递到函数的形参里! 
    fn.call.call.call.call(fn,1,2,3); 同上一条原理!
    
    
    概括性总结:
    不怎么理解的话也可以记住这个概括性诀窍:
    碰到两个及两个以上的call都是让第一个参数执行,第一个参数必须是函数;
    第二个参数是改变第一个参数中this;
    第三个及第三个以后的参数作为实参传给第一个参数。
  • 相关阅读:
    Vulkan
    C# Optimization
    C# Bridge Pattern(Handle/Body)
    Favorite Games
    Unity Particle System Sorting Order
    UGUI
    C# Language Specification
    接口的显式实现和隐式实现
    C#反射机制
    wcf 使用sqlMembership证书认证
  • 原文地址:https://www.cnblogs.com/joer717/p/10654090.html
Copyright © 2011-2022 走看看