zoukankan      html  css  js  c++  java
  • JavaScript函数之实际参数对象(arguments) / callee属性 / caller属性 / 递归调用 / 获取函数名称的方法

    函数的作用域:调用对象

      JavaScript中函数的主体是在局部作用域中执行的,该作用域不同于全局作用域。这个新的作用域是通过将调用对象添加到作用域链的头部而创建的(没怎么理解这句话,有理解的亲可以留言告诉我, 谢谢)。因为调用对象是作用域链的一部分,所以在函数体内可以把这个对象属性作为变量来访问。

      调用对象的属性包括:用var声明的局部变量,函数形参,还有一种特殊的属性arguments

    函数的实际参数:实际参数对象

      arguments对象,用来引用实际参数对象。函数的arguments对象并不是一个数组,访问单个参数的方式与访问数组元素的方式相同。索引 n 实际上是arguments对象的 0…n 属性的其中一个参数。

    (function f(){//求和函数
        var i,sum=0;
        for(i=0;i<arguments.length;i++){
            sum+=arguments[i];
        }
        return  sum;
    })(1, 2, 3);//输出: 6

    需要说明的是:JavaScript函数并不会检查参数的类型和数量

    arguments属性callee(JavaScript 1.2新属性)

      实际参数对象的callee属性引用了当前正在执行的函数。这在未命名的 函数递归调用 自身时非常有用

    (function(x){//求x的阶乘
        if(typeof x == "number" && x >0){
            return x * arguments.callee(x-1);
        }
        return 1;//当x等于0时输出1
    })(5);//输出: 120

    arguments属性caller

      实际参数对象的caller属性引用的是当前函数被调用的调用环境(说白了就是返回一个函数(F)的引用,该函数(F)调用了当前函数)。

      注意:arguments.caller引用的不是调用当前函数的那个函数,而是调用当前函数的函数的实际参数对象。所以要引用调用函数,必须使用functionName.caller.callee

          但是在JavaScript的实际实现中, 它直接引用了调用函数,而不是调用函数的实际参数对象。

    (function(){
        function inner(){
            return inner.caller
        }
        return inner();
    })();
    /*输出:
    function(){
        function inner(){
            return inner.caller
        }
        return inner();
    }
    //根据大家的说法,这个输出的是原函数的反编译的文本
    //这个caller并不是在定义时就确定的上下文环境,而是在实际调用中动态生成的。
    function inner(){
        return f.caller;
    }
    (function (){
        return inner();
    })();
    //输出:function (){
    //        return inner();
    //     }
    */
    //需要说明的是:如果当前函数是顶层函数, functionName.caller返回的是null

      疑惑:这个caller的实际用途到底是什么???还希望有实际案例的朋友可以留言告诉我

      (看到网上的说法:caller的应用场景 主要用于察看函数本身被哪个函数调用。但是本人还是没有想到,什么养的情况下需要查看自身被那个函数调用了,不过在《JavaScript权威指南》里给出了一个例子,应用caller属性来编写一个调试函数,用来输出一个栈的踪迹[追踪栈的函数])

    获取函数名称的方法

    //针对function xxx(){}定义函数方法
    var reg = /function *(w*)(w*)/;
    function test(){};
    var funName = test.toString().match(reg);
    if(funName){
        console.log(funName[1]);//输出: test
    }
    
    //针对var xxx = function(){}定义方式
    var test  = function(){};
    var funName = test.toString().match(reg);
    if(funName && funName[1] == ""){ console.log("该函数是匿名函数"); }
  • 相关阅读:
    preventDefault
    YII2中的Html助手和Request组件
    yii2 输出json的方法
    FormData异步上传
    通过Ajax方式上传文件,使用FormData进行Ajax请求
    Yii设置Cache缓存的方法
    exif_imagetype() 函数在linux下的php中不存在
    Thinkphp整合各个功能
    PHP cURL库函数抓取页面内容
    javascript实现打印功能
  • 原文地址:https://www.cnblogs.com/caoruiy/p/4435916.html
Copyright © 2011-2022 走看看