• JS Function.call深入


    Function.call深入

    var ary = [12, 23, 34]
    

    ary.slice
    ary这个实例通过原型链的查找机制找到Array.prototype上的slice方法

    ary.slice() 让找的slice方法执行, 在执行slice方法的过程中, 才把ary数组进行了截取

    Funciton.call用法

    call方法:
    首先让原型上的call方法执行, 在执行call方法的时候, 让fn方法中的this变为第一个参数值obj, 然后再把fn这个函数执行

    call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面

    Function.prototype.call = function(){}

    var obj = {name: 'lemon'}
    function fn(){
        console.log(this);
    }
    fn();
    obj.fn();
    fn.call(obj);
    

    -> window
    ->Uncaught TypeError: obj.fn is not a funciton
    ->{name: 'lemon'}

    模拟一个call方法

    1. 让fn中的this关键字变为context的值 obj
    2. 让fn方法执行
    Function.prototype.myCall = function (context, ...args) {
        context = context || window;
        context.__proto__.fn = this;
        const result = context.fn(...args);
        // 执行fn时上下文context已被修改,不是我们所期望的call 
    
        delete context.__proto__.fn;
        return result;
    }
    fn.myCall(obj)
    

    一道练习题

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

    ->2

    先执行fn1.call.call(fn2)
    通过fn1的原型链找到call函数
    通过找到call函数的原型链找到call
    执行call.call(fn2), -> 2

    1. 前面的一串 fn.call.call.call.call 并没有调用,只是获取对象的call属性,所以,这一串的结果是 Function.call 属性。
    2. 所以那一串 就是 Function.call.call(fn2);还可以解理为 fn3.call(fn2)。
    3. 根据call的原理(可参考上面的call模拟),在 fn3执行call,其实际是这样执行的 fn2.fn3()。
    4. 由于 fn3实际上就是 call 函数,所以, fn2.fn3() 等价于 fn2.call()。
    5. 所以,上面那一串代码的最终结果,就是调用 fn2,所以结果输出 22.

    概括性总结:
    不怎么理解的话也可以记住这个概括性诀窍:
    碰到两个及两个以上的call都是让第一个参数执行,第一个参数必须是函数;
    第二个参数是改变第一个参数中this;
    第三个及第三个以后的参数作为实参传给第一个参数。

  • 相关阅读:
    保护【大数据】应用的步骤和工具
    提高UI设计效率的4个技巧
    你学会UI设计了吗?
    Android 零散知识点整理
    PHP面试和PHP开发者都应掌握的10个问题
    MySQL 中如何存储 emoji ?
    想在网上保持匿名?教你用Linux如何实现!
    数据库入门之运行原始 SQL 查找
    PHP之取得当前时间函数方法
    【在线】使用在线软件来完成任务
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13645817.html
Copyright © 2020-2023  润新知