javascript中caller和callee call和apply

Arguments : 

该对象代表正在执行的函数和调用它的函数的参数。

[function.]arguments[n] 参数function :选项。当前正在执行的 Function 对象的名字。 
n :选项, 要传递给 Function 对象的从0开始的参数值索引。 
说明Arguments :是进行函数调用时,除了指定的参数外,还另外创建的一个隐藏对象。Arguments是一个类似数组但不是数组的对象,说它类似数组是因为其具有数组一样的访问性质及方式,可以由arguments[n]来访问对应的单个参数的值,并拥有数组长度属性length。还有就是arguments对象存储的是实际传递给函数的参数,而不局限于函数声明所定义的参数列表,而且不能显式创建 arguments 对象。arguments 对象只有函数开始时才可用。下边例子详细说明了这些性质://arguments 对象的用法。 

在此添加了一个说明arguments不是数组(Array类)的代码:
//arguments 对象的用法。

 1         function ArgTest(a, b){
 2             var i, s = "The ArgTest function expected ";
 3             var numargs = arguments.length;      // 获取被传递参数的数值。
 4             var expargs = ArgTest.length;        // 获取期望参数的数值。
 5             if (expargs < 2)
 6                s += expargs + " argument. ";
 7             else
 8                s += expargs + " arguments. ";
 9             if (numargs < 2)
10                s += numargs + " was passed.";
11             else
12                s += numargs + " were passed.";
13             s += "\n\n";
14             for (i =0 ; i < numargs; i++){       // 获取参数内容。
15             s += "   Arg " + i + " = " + arguments[i] + "\n";
16             }
17             return(s);                           // 返回参数列表。
18         }
19         ArgTest(123,456,789);

在此添加了一个说明arguments不是数组(Array类)的代码:

1         Array.prototype.selfvalue = 1;
2         alert(new Array().selfvalue);
3         function testAguments(){
4              alert(arguments.selfvalue);
5         }

运行代码你会发现第一个alert显示1,这表示数组对象拥有selfvalue属性,值为1,而当你调用函数testAguments时,你会发现显示的是“undefined”,说明了不是arguments的属性,即arguments并不是一个数组对象。

caller:

返回一个对调用function函数的函数的引用(用法:function.caller)

说明:对于函数来说,caller属性只有在函数执行时才有定义。如果函数由顶层调用,caller则为null。

 1 var time = 3 //控制次数,去掉会一直在caller与handleCaller交替不断执行
 2 function caller() {
 3     caller.caller()//返回调用caller函数的函数引用
 4 }
 5 function handleCaller() {
 6     if (time > 0){
 7         time--
 8         alert(handleCaller.caller)//返回调用handleCaller函数的函数引用
 9         alert(caller.caller)//返回调用caller函数的函数引用
10         caller()
11     }
12 }
13 handleCaller()

例子分析:第一次handleCaller运行的时候,两个alert返回的都是null,alert(handleCaller.caller)返回null是因为它是由顶层调用, alert(caller.caller)返回null是因为caller的默认值是null。接下去caller()函数被调用,caller.caller返回的是调用它的函数(handleCaller)的引用,通过caller.caller()可以再次调用handleCaller函数。第二次handleCaller运行的时候,alert(handleCaller.caller)返回的是caller代码(其实就是caller的引用),alert(caller.caller)返回的是handleCaller代码。因为函数之间的调用关系是handleCaller->caller->handleCaller。之后就不断在2个函数之间交替执行。

callee:

返回相对应的arguments的函数引用。(多用于匿名函数递归)

说明:也许你在网上看到最多的是callee返回正在执行的函数引用。我是这么理解,每个函数都有一个自己的arguments,通常是用来存放参数的。arguments有一个callee 属性,初始值就是对应自身的函数引用。当你函数执行到该语句时,arguments是默认对应的是你现在执行的函数,那么arguments.callee为当前正在执行的函数的引用。当然如果你有标记过其他函数的arguments(例子中的args),自然可以用args.callee()去再次调用那个函数。

 1 function a(){
 2     alert(arguments.callee)
 3     var args = arguments
 4     function c(){
 5         alert(arguments.callee)
 6         args.callee()
 7     }
 8     c()
 9 }
10 a()

 例子分析:例子中的arguments.callee都是默认返回当前正在执行的函数的引用(a中返回a自身函数引用,c中返回c自身函数引用),而通过用args存放a函数的arguments,在内置函数c中使用args.callee()再次调用a函数。

apply and call  :

它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数方式有所区别:

    apply( thisArg , argArray );  call( thisArg[,arg1,arg2…] ] );

    即所有函数内部的this指针都会被赋值为 thisArg,这可实现将函数作为另外一个对象的方法运行的目的

    apply的说明:如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisArg任何一个参数,那么 Global 对象将被用作thisArg, 并且无法被传递任何参数。 

    call的说明 :call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisArg指定的新对象。如果没有提供 thisArg参数,那么 Global 对象被用作 thisArg

    相关技巧:

         应用call和apply还有一个技巧在里面,就是用 call 和 apply 应用另一个函数(类)以后,当前的函数(类)就具备了另一个函数(类)的方法或者是属性,这也可以称之为"继承"

 1     // 继承的演示
 2    function base() {
 3         this.member = " dnnsun_Member";
 4         this.method = function() {
 5             window.alert(this.member);
 6         }
 7    }
 8    function extend() {
 9         base.call(this);
10         window.alert(member);
11         window.alert(this.method);
12    }

 上面的例子可以看出,通过call之后,extend可以继承到base的方法和属性。 

posted @ 2015-08-10 09:41  Lz_Tiramisu  阅读(229)  评论(0编辑  收藏  举报