zoukankan      html  css  js  c++  java
  • 函数学习之参数(arguments对象)

    函数声明语句:function f(x){},其中x就是参数。

    参数分为两种:

    • 形参(parameter):函数定义时圆括号里的数据。
    • 实参(arguments);函数调用时,传给函数作为参数的数据。

    EMCAScript规定在调用函数时,可传入任意数量,任意类型的参数,可以不跟函数定义时传入的形参数量相对应。为什么会这样呢?

    原因就是,EMACAScript中的参数在内部是用一个数组来表示的,函数接收的始终是这个数组,而不关心包含哪些参数。而且,在函数体内也可以通过arguments这个对象来访问这个参数数组,从而获取传递给函数的每一个参数。(arguments就是一个对象--函数的一个内部对象,和this一样。)因此arguments看起来就像一个类数组了。可以用arguments[n]来访问各个位置的元素了.

    要了解arguments对象,就需要先函数的内部属性。

    函数内部,有两个特殊对象:arguments 和 this。

    arguments是一个类数组对象,包含着传入函数中的所有参数。该对象有一个属性callee,该属性是一个指针,指向拥有这个arguments对象的函数。经典例子是阶乘函数:

     
     1 function factorial(num){
     2     if(num <= 1){
     3         return 1;
     4     }else{
     5         return num * factorial(num-1);
     6     }
     7 }
     8 
     9 //修改一下,消除函数的执行与函数名紧密的耦合在一起,
    10 function factorial(num){
    11     if(num <= 1){
    12         return 1;
    13     }else {
    14         return num * arguments.callee(num-1);
    15     }
    16 }
    17 
    18 //修改后函数名factorial就没出现在函数体内部,因此,无论引用函数时使用什么名字,都能保证正常完成递归。
    19 //例如
    20 var trueFactorial = factorial;
    21 factorial = function(){
    22     return 0;
    23 };
    24 alert(trueFactorial(5));  //120
    25 alert(factorial(5));   //0
    26 //在上面的例子里,变量trueFactorial 获得了factorial的值,实际上就是在另一个位置上保存了一个指向函数的指针,就是让另一个变量也可以应用该函数,正如在函数定义时说的,函数名是一个指向函数的指针,函数体本身存在那里,通过函数名可以访问罢了,二者相互独立,又存在某种联系。
    27 //然后将一个返回0的新函数赋给变量factorial。如果在函数体内有变量名factorial,如第一个例子,则trueFactorial()就会返回0.但改成arguments.callee后就能够让trueFactorial正常计算。
     

    与callee属性对应的就是caller属性,arguments对象也拥有caller属性,即:arguments.caller。但在严格模式下访问它会报错,而在非严格模式下这个属性始终是undefined。该属性主要就是为了分清arguments.caller和函数的caller属性。函数的caller属性指向调用该函数的外部函数。

    arguments.callee.caller 和函数的caller属性等效。

     
    function outer(){
        inner();
    }
    function inner(){
        alert(inner.caller);  //等价于alert(arguments.callee.caller);
    }
    outer();   //返回outer函数的代码
     

    arguments还有一个length属性,返回传入参数的个数。和Array.length类似。

    前面说的在函数内部可以通过arguments对象访问传入的参数。那也可以和命名参数一起在函数内部使用:

     
    function doAdd(num1,num2){
        if(arguments.length == 1){
            alert(num1 + 10);
        }else if(arguments.length == 2){
            alert(arguemnts[0] + num2);
        }
    }
     

    还有一点。arguments的值永远与对应的命名参数保持同步:

    1
    2
    3
    4
    function doAdd(num1,num2){
        arguments[1] = 10;
        alert(arguments[0] + num2);
    }

      什么意思呢?就是每次执行这个函数时,里面的arguments[1]都会被设成10,对应的num2也会跟着变着10。

    最后一点:没有传递值的命名参数将自动被赋予undefined,就像变量没有初始化一样。

    关于函数定义时的参数,其实就像在函数内部定义的变量一样,只不过不用在显性的使用var来进行定义。

    来源:https://www.cnblogs.com/liurenxingyu/p/5118724.html

  • 相关阅读:
    缓存概述
    进程Process
    MVC系统过滤器、自定义过滤器
    暂无,进程那篇深度不够
    SeasLog 与 monolog 日志系统的区别,SeasLog安装步骤
    阿里面试官:说一下从url输入到返回请求的过程,问的难度就是不一样!
    [技术分享]OSI七层模型详解
    Mysql引擎介绍及InnoDB逻辑存储结构
    Paypal 实现自动订阅
    PayPal 支付Checkout 收银台和 Subscription 订阅计划全过程分享
  • 原文地址:https://www.cnblogs.com/sanerandm/p/8463178.html
Copyright © 2011-2022 走看看