zoukankan      html  css  js  c++  java
  • arguments详解——函数内命名参数之映射

    首先,arguments对象是所有(非箭头)函数中都可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引0处。

    arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。但是它可以被转换为一个真正的Array,

    以下为四种方式:已验证

    var args = Array.prototype.slice.call(arguments);
    var args = [].slice.call(arguments);
    
    // ES2015
    const args = Array.from(arguments);
    const args = [...arguments];

    1,非严格模式下,arguments与调用函数时传入的参数一一对应,不管是否有命名参数,

      不存在命名参数时,参数只能通过arguments[i]调用;

      存在命名参数时,参数可以通过arguments[i]或者参数名进行调用,映射关系,修改一个另一个也有变化(前提是命名参数与传入的参数数量相同,否则请看第二点)

      无命名参数时:

    console.log('---------------------使用arguments参数对所有函数执行操作------------------------');
    //完全没有任何显式定义参数的函数
    //迭代所有传入参数,然后通过索引标记获取每个元素的值
    function sum() {
      var sum = 0;
      for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
      }
      return sum;
    }
    //调用函数并传入任意数量的参数
    if (sum(1, 2) === 3) {
      console.log("We can add two numbers.");
    }
    if (sum(1, 2, 3) === 6) {
      console.log("We can add three numbers");
    }
    if (sum(1, 2, 3, 4) === 10) {
      console.log('We can add four numbers.');
    }

      存在命名参数时:

    console.log('-------------argument对象作为函数参数的别名----------------------');
    //argument参数有一个有趣的特性:它可以作为函数参数的别名。例如,如果为arguments[0]赋一个新值,那么,同时也会改变第一个参数的值。
    //检查person参数的值等于gardener,并作为第一个参数被传入。
    function infiltrate(person) {
      if (person === 'gardener') {
        console.log("The person is a gardener.");
      }
     
      if (arguments[0] === 'gardener') {
        console.log('The first argument is a gardener');
      }
     
      arguments[0] = 'ninja';
      //改变argument对象的值也会改变相应的形参
      if (person === 'ninja') {
        console.log('The person is a ninja now.');
      }
      if (arguments[0] === 'ninja') {
        console.log('The first argument is a ninja.');
      }
     
      person = 'gardener';
     
      //这两种方式下,别名都正常工作了。
      if (person === 'gardener') {
        console.log('The person is a gardener once more.');
      }
      if (arguments[0] === 'gardener') {
        console.log('The first argument is a gardener again.');
      }
     
    }
     
    infiltrate("gardener");

    2,非严格模式下arguments的length属性在调用函数完成后不可改变:

      2.1通过arguments[i]添加新的属性也不客改变length属性

      2.2通过arguments[i]添加的新属性可以通过arguments[i]访问到

      2.3若传入参数少于定义参数那么在函数内部对定义参数赋值,新参数不可以通过arguments[i]访问到,且不客改变length属性(函数的定义参数是函数内部作用域的已定义变量,与在函数内部定义的变量没有不同)

      综上所述,若传入参数不等于定义参数,那么多出的定义参数或者arguments则失去映射关系,如下所示:

      

            function a(a,b,c){
                arguments[2] = 10
                console.log(arguments[2],c,arguments.length)
            }
    
            a(1,2,4)
    
            a(5,6)    

        function a(a,b,c){
                c = 10
                console.log(arguments[2],c,arguments.length)
            }
    
            a(1,2,4)
    
            a(5,6)

    3,将arguments对象作为函数参数的别名使用时会影响代码的可读性,因此在JavaScript提供的严格模式中(strict mode)中将无法再使用它。arguments对象将不再作为参数的别名

    <script type="text/javascript">
        "use strict";
         console.log('--------使用严格模式避免使用arguments别名---------------');
        function infiltrate(person) {
          if (person === 'gardener') {
            console.log("The person is a gardener.");
          }
     
          if (arguments[0] === 'gardener') {
            console.log('The first argument is a gardener');
          }
          //改变第一个参数
          arguments[0] = 'ninja';
       //Person的参数值没有改变
          if (person === 'ninja') {
            console.log('The person is a ninja now.');
          }
    //第一个参数值被改变了
          if (arguments[0] === 'ninja') {
            console.log('The first argument is a ninja.');
          }
        }
        infiltrate('gardener');
    </script>

    第一行代码use strict是一个简单的字符串,这将告诉JavaScript引擎,我们希望将下面的代码在严格模式下执行。严格模式将改变程序的执行结果,最终person参数的值和arguments参数的第一个中将不再相同。

    //改变第一个参数

    arguments[0] = 'ninja';

    //Person的参数值没有改变

    if (person === 'ninja') {

    console.log('The person is a ninja now.');

    }

    //第一个参数值被改变了

    if (arguments[0] === 'ninja') {

    console.log('The first argument is a ninja.');

    }

    但与非严格模式不同的是,这一次arguments对象将不再作为参数的别名。如果想通过arguments[0]='ninja'改变第一个参数的值,这将不会改变person参数。

    参考:javascript 理解函数调用-操作arguments参数 https://blog.csdn.net/zhangying1994/article/details/86529770

      理解函数参数及arguments https://www.jianshu.com/p/75f8fa2ad073

      JS中的arguments参数 https://blog.csdn.net/zjy_android_blog/article/details/80934042

      Arguments 对象 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments

  • 相关阅读:
    创建可管理的对象属性
    解析简单xml文档
    定义类的__slots__属性节省内存的开销
    读写json数据
    读写csv,excel文件数据
    常用的字符串处理方法
    sql中case when 的使用
    对字典的处理
    元组的元素命名
    列表,字典,集合按条件筛选
  • 原文地址:https://www.cnblogs.com/wangtong111/p/11303191.html
Copyright © 2011-2022 走看看