zoukankan      html  css  js  c++  java
  • 函数arguments对象

         ECMAScript 函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript 函数不介意传递进来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即便你定义的函数只接收两个参数,在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不会有什么怨言。

        之所以会这样,原因是ECMAScript 中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数。

        其实,arguments 对象只是与数组类似(它并不是Array 的实例),因为可以使用方括号语法访问它的每一个元素(即第一个元素是arguments[0],第二个元素是argumetns[1],以此类推),使用length 属性来确定传递进来多少个参数。通过访问arguments 对象的length 属性可以获知有多少个参数传递给了函数

        ECMAScript 函数的一个重要特点:命名的参数只提供便利,但不是必需的。另外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但在ECMAScript 中,没有这些条条框框,解析器不会验证命名参数。

    function howManyArgs() {
                alert(arguments.length);
            }
            
            howManyArgs("string", 45);    //2
            howManyArgs();                //0
            howManyArgs(12);              //1

    另一个与参数相关的重要方面,就是arguments 对象可以与命名参数一起使用。例如:

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

    关于arguments 的行为,还有一点比较有意思。那就是它的值永远与对应命名参数的值保持同步

            function doAdd(num1, num2) {
                //if(arguments.length == 1) {
                    arguments[1] = 10;
                //}
                alert(arguments[0] + num2);
            }
    
            doAdd(10, 20);        //20
            doAdd(30, 20);        //40

    由上面的例子可以看出,arguments对象中的值会自动反映到对应的命名参数。不过,这并不是说读取这两个值会访问相同的内存空间;它们的内存空间是独立的,但它们的值会同步

    另外还要记住,如果只传入了一个参数,那么为arguments[1]设置的值不会反应到命名参数中。这是因为arguments 对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的

    关于参数还要记住最后一点:没有传递值的命名参数将自动被赋予undefined 值。这就跟定义了变量但又没有初始化一样。例如,如果只给doAdd()函数传递了一个参数,则num2 中就会保存undefined 值。

    注意:ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数。

    另外ECMAScript 函数没有函数重载特性!(因为不存在函数签名(接收的参数的类型和数量)的特性)

    ECMAScript 函数不能像传统意义上那样实现重载。而在其他语言(如Java)中,可以为一个函数编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。如前所述,ECMAScirpt函数没有签名,因为其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可能做到的。

    后定义的函数会覆盖掉先定义的函数。但通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。




    参考《JS高程》第三版P64-67

  • 相关阅读:
    git的使用
    open():打开文件
    结合python+selenium使用AutoIt V3实现文件、图片上传
    Postman教程
    Python字符串切片
    python实现操作excel,数据写入excel的一行或者一列
    python打包exe
    spring boot基于DRUID数据源密码加密及数据源监控实现
    基于aop的日志记录方式实现
    Android中ContentProvider的简单使用
  • 原文地址:https://www.cnblogs.com/guorange/p/6644813.html
Copyright © 2011-2022 走看看