• call深入理解


    function fn1() {
        console.log(1);
    }
    function fn2() {
        console.log(2);
    }
    fn1.call(fn2); // 1
    fn1.call.call(fn2); // 2

      
    首先fn1通过原型链找到Function.prototype上的call方法,然后再让call方法通过原型再找到Function原型上的call(因为call本身的值也是一个函数,所以同样可以让Function.prototype),在第二次找到call的时候再让方法执行,方法中的thisfn1.call,而this被fn2替代,然后再让fn1.call执行。
    Function.prototype.call = test;
    function test (context) {
        // 改变fn中的this关键字
        // eval(....);
        
        // 让fn方法执行
        this(); // 此时的this就是fn1
    };

     fn1.call.call(fn2)就是test.call(fn2);test.call(fn2)中的this就是test,然后把call中this改成fn2,然后执行

    Function.prototype.call = test;
    function test (context) {
        // 改变fn中的this关键字
        // eval(....);
        
        // 让fn方法执行
        fn2(); //2
    };

        

    Function.prototype.myCall=function(myobj,...args){
            if(typeof myobj==='Function'){
                 throw new TypeError('error')
           }
          const  fn=symbol('fn')    //唯一值
          myobj=myobj || window  //若没有传入对象,则绑定到window上
          myobj[fn]=this         //把函数赋值到对象的某个属性
          const result=myobj[fn](...args)
         delete  myobj[fn]       //删除fn声明
         return result
    }

       结合mycall分析:

    • 先将 fn2 赋给临时变量 myobj。
    • this 所指向的对象就是一个函数对象:Function.prototype.myCall()。所以赋给 object.fn 临时属性指向的就是 Function.prototype.myCall()方法。
    • 由于 arguments 长度为 1,所以直接执行 myobj.fn()方法,也就是 myobj.myCall(),也就是 fn2.myCall()
    • fn2.myCall()实际上执行的是 global.fn2(),具体执行过程就不再熬述了,故输出了 2,没有返回值。

    对call,apply的看法,理解 

    首先需要了解apply,call的基本用法,其目的是改变调用方法中的this指向,将其指向为传入的对象

    var console = window.console || {log: function () {}};   
    var log = console.log;  
    console.log = function(tips,message){   
       Function.prototype.apply.call(log, console, arguments);   
       //Function.prototype.call.call(log, console, arguments);  
       //Function.prototype.call.apply(log, [console, arguments]);   
        
     //传统方式  
     //var args=[].slice.call(arguments);  
     //log.apply(console,args);  
    }  
    

      

    分析:

          该怎么理解Function.prototype.apply.call(log,console,arguments);呢

          首先可以将Function.prototype.apply看成一个整体-->FunctionApply

           FunctionApply.call(log,console,arguments);

           那么将此句翻译一下

           log.FunctionApply(console,arguments);

           然后再翻译一下,你就懂了吧,就是一个普通方法调用了

           console.log(arguments);

    Function.prototype.call.apply(log,[console.arguments]);

    FunctionCall.apply(log,[console,arguments]);  
    log.FunctionCall(console,arguments);  
    console.log(arguments);  
    

    tips:

        Function.prototype.apply.call  等同于Function.prototype.call.call

        Function.prototype.call.apply  等同于 Function.prototype.apply.apply

    function testA(a){  
        console.log('aaaa',a);  
    }  
    Function.prototype.apply.call(testA,window,['Mike']) == testA.apply(window,['Mike']) == window.testA('Mike');  
    //Function.prototype.call.call(testA,window,['Mike']);  
    //Function.prototype.apply.apply(testA,[window,['Mike']]);  
    //Function.prototype.call.apply(testA,[window,['Mike']]);  
    

      

      

  • 相关阅读:
    PHP培训教程 PHP里10个鲜为人知但却非常有用的函数
    跟我学Spring Boot(一)创建Spring Boot 项目
    android 4.0 webview 无法播放视频
    vs2008 安装部署 启动项
    android 使用webview 加载网页
    hbase 无法打开60010网页
    oracle 提示没有监听
    hbase 基本命令
    hbase 单机版安装
    win7 64位远程连接oracle11g64位
  • 原文地址:https://www.cnblogs.com/wmydb/p/9155885.html
Copyright © 2020-2023  润新知