zoukankan      html  css  js  c++  java
  • 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 += "
    
    ";
    14             for (i =0 ; i < numargs; i++){       // 获取参数内容。
    15             s += "   Arg " + i + " = " + arguments[i] + "
    ";
    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的方法和属性。 

  • 相关阅读:
    redis在linux下的安装
    Redis在系统中的使用
    使用ServiceStackRedis操作redis
    Redis命令
    mongo增删改操作
    mongo c#驱动介绍操作
    LeetCode 19 删除链表的倒数第N个节点
    LeetCode 01 两数之和
    metapath2vec 笔记
    Q&A(一)
  • 原文地址:https://www.cnblogs.com/Iona/p/4717117.html
Copyright © 2011-2022 走看看