javascript 理解函数调用-操作arguments参数

60 篇文章 0 订阅
55 篇文章 1 订阅
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.');
}

 

上述代码中,我们首先定义了一个没有显示声明任何参数的sum函数,尽管如此,我们依然可以通过arguments对象访问所有的函数参数。遍历所有的参数即可计算它们的和。

因此,我们可以调用函数并传入任意数量的参数,接着我们通过测试几种情况。
           注意:
           我们之前提到过,在大多数情况下可以使用剩余参数(rest parameter)来代替arguments参数。剩余参数是正真的Array实例,也就是说你可以在它上面直接使用所有的数组方法。这点相对于arguments对象而言是个优势,作为练习可以使用剩余参数代替arguments参数。argument参数有一个有趣的特性:它可以作为函数参数的别名。例如,如果为arguments[0]赋一个新值,那么,同时也会改变第一个参数的值。

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");

 

这里可以说明arguments对象是如何作为函数参数别名的。我们定义了一个函数infiltrate,它只接收一个参数person,接着我们调用它并传入参数gardener。可以同时通过函数形参person和arguments对象访问到参数值gardener。

 

if (person === 'gardener') {

console.log("The person is a gardener.");

}

 

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

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

}

 

因为arguments对象是函数参数参数的别名,所以如果改变了arguments对象的值,同时也会影响对应的函数参数

 

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.');

}

 

反之亦然。如果我们更改了某个参数的值,会同时影响参数和arguments对象:

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.');

}

 

 

避免使用别名

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

严格模式

严格模式是在ES5中引入的特性,它可以改变JavaScript引擎的默认行为并执行更加严格的语法检查,一些在普通模式下的静默错误会在严格模式下抛出异常。在严格模式下部分语言特性会被改变,甚至完全禁用一些不安全的语言特性,其中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忍者秘籍》

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值