zoukankan      html  css  js  c++  java
  • caller 和 callee

    caller 和 callee

    caller 以及 callee是比较少见的属性,可能才了解前端的童鞋都认识。

    callee是arguments的属性,值为调用该参数的函数(即是该函数)。

    function apple () {
        console.log(arguments.callee) // apple();
    }
    

    caller是function的属性,值为调用该函数的函数(若函数为顶层函数,则返回null)。

    function banana () {
        apple();
    }
    function apple () {
        console.log(apple.caller) // banana()
    }
    

    这两个属性用的越来越少,一方面是因为函数本身的属性应用场景少,例如name,length,constructor,另一方面,es6箭头函数的推出,让箭头函数不再持有arguments与caller。在es6中使用,会产生如下错误信息,提示是受限的属性。

    'caller' and 'arguments' are restricted function properties and cannot be accessed in this context.
    

    严格模式中也无法使用arguments,且当函数为匿名函数的时候,callee返回undefined。

    我只说下个人对于这两个属性的应用的小小见解。

    callee

    在递归中,如下

    function factorial(n, total) {
        if (n === 1) return total;
        return factorial(n - 1, n * total);
    }
    
    factorial(5, 1) // 120
    

    这个函数中 factorial 在函数体内也出现,通俗地说就是如果我要修改函数名,需要修改两处。如果用下面的方式就只用修改一次。

    function factorial(n, total) {
        if (n === 1) return total;
        return arguments.callee(n - 1, n * total);
    }
    

    caller

    这个可以查看函数的调用链,如下:

    function main () {
        apple();
    }
    function orange() {
        watermelon()
    }
    function watermelon() {
        peach()
    }
    function grape() {
        lemon()
    }
    function lemon() {
        summary();
    }
    function peach() {
        grape();
        // console.log(arguments.callee.caller.name);
    }
    function apple() {
        orange();
    }
    function summary() {
        let arg = arguments.callee;
        let arr = [arguments.callee.name];
        function _summary(a) {
            if(a.caller) {
                arr.unshift(a.caller.name.toString());
                _summary(a.caller);
            } else {
                console.log(arr.join('->'))
            }
        }
        return _summary(arg);
    }
    console.log(main())
    

    结果为

    main->apple->orange->watermelon->peach->grape->lemon->summary
    

    加一点场景,更好理解,例如,李太太出门买水果(main),买了一个后买另一个,到家后开始结算(summary),忘记了自己买水果的顺序,那么上列的结果就阐明了买水果的顺序。


    最近写了一些东西,都没有提交,一方面是工作中有些忙,另一方面,也反思了一下自己是否有些急躁冒进了。

    前端的框架百花齐放,而知识点又星罗棋布,一方面忙于学习新框架的使用,另一方面还要查漏补缺,极少有时间抬头看看,自己是不是还走在正确的道路上。

    正如,在学习框架的时候,自己有没有想过它是怎么实现的,大部分人都把框架当作一个黑盒子,输入数据进去,给我答案出来,这只能说明框架足够优秀。

    读《哈姆雷特》的是读者,而写哈姆雷特的是莎士比亚。

    阅读了太多的东西,总渴望自己写点什么,让别人认可。

    此后,还会陆续更新自己微薄的见解,与有缘相遇的大家,共同进步。

  • 相关阅读:
    java正则表达式
    SpringAOP03 项目脚手架、自定义注解、织入切面、引介增强
    SpringAOP02 自定义注解
    servlet01 项目demo、servlet生命周期
    SpringBoot15 sell02 订单模块
    SpringBoot15 sell01 项目创建、MySQL数据库连接、日志配置、开发热部署、商品信息模块
    datatables01 安装、数据源、选中行事件、新增一行数据、删除一行数据
    Navicat 连接阿里云的 MySQL
    linux内核中ip,tcp等头的定义(转)
    TCPflow:在Linux中分析和调试网络流量的利器(转)
  • 原文地址:https://www.cnblogs.com/mydia/p/7494720.html
Copyright © 2011-2022 走看看