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("该函数是匿名函数"); }

 

你可能感兴趣的:(JavaScript)