JavaScript中的arguments参数数组解析

关于arguments的长度

arguments是在普通函数中的参数数组,使用它来访问传入的每个参数值。

arguments是一个伪数组的形式,其长度依据函数调用时传入的参数数目而定,若在函数中没有显示修改这个属性,则这个属性不会随着手动使用下标添加元素而更改。

在一个函数当中, 使用下标访问元素修改arguments数组:

      arguments[9] = 1;
      console.log("the arguments' length is ", arguments.length);
      console.log(arguments);

输出结果为:

the arguments' length is  1
Arguments(1) [0, 9: 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]

//这里的Arguments后面的(1)是我自己添加的,chrome在长度为1的时候不会输出

可以看出,是为arguments增加了一个以下标为键的键值对。

若在使用下标修改arguments之前显式的修改length属性的值,后修改的数据的下标若在length范围内,则会增加到”数组“内,反之则依旧会增加一个以下标为键的键值对。

      arguments.length = 3;
      arguments[1] = 1;
      arguments[9] = 1;
      console.log("the arguments' length is ", arguments.length);
      console.log(arguments);

输出结果为:

the arguments' length is  3
Arguments(3) [0, 1, empty, 9: 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]

如果是正常的一个数组,其length属性值会随着数组的修改而变动:

    let arr = [1];
    arr[9] = 1;
    console.log(arr,arr.length);

输出结果:(10) [1, empty × 8, 1] 10

关于参数之间的同步

在非严格模式下,arguments中的元素会与传入的有名字的参数相互影响、保持同步。

    let fn = function (num1, num2, num3) {
      console.log("num1=", num1, ",num2=", num2, ",num3=", num3);
      console.log("arg[1]=", arguments[0], ",arg[2]=", arguments[1], ",arg[3]=", arguments[2]);
      console.log(arguments);
      console.log("");
      console.log("change num1 to 0...");
      console.log("change arg[2] to 1...");
      console.log("change arg[3] to 2...");
      num1 = 0;
      arguments[1] = 1;
      arguments[2] = 2;
      console.log("");
      console.log("num1=", num1, ",num2=", num2, ",num3=", num3);
      console.log("arg[1]=", arguments[0], ",arg[2]=", arguments[1], ",arg[3]=", arguments[2]);
      console.log(arguments);
    }
    fn(123,321);

在上述例子当中,我向fn当中传入参数的时候,仅仅传入了两个参数,这两个参数会在有名参数与arguments参数之间相互保持同步。而第三个参数num3,因为没有传入,并没有在有名参数和arguments参数之间同步。

输出结果为:

num1= 123 ,num2= 321 ,num3= undefined
arg[1]= 123 ,arg[2]= 321 ,arg[3]= undefined
Arguments(2) [123, 321, callee: ƒ, Symbol(Symbol.iterator): ƒ]

change num1 to 0...
change arg[2] to 1...
change arg[3] to 2...

num1= 0 ,num2= 1 ,num3= undefined
arg[1]= 0 ,arg[2]= 1 ,arg[3]= 2
Arguments(2) [0, 1, 2: 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]

同理,我在上面的fn函数当中,显示修改num3的值,其结果也不会被同步到arguments参数中对应下标位置上面去。

总结的来讲:非严格模式下,arguments参数会与传入的有名字的参数保持同步

下面是严格模式下的输出结果,除了增加“use strict”;语句,其他代码不变:

num1= 123 ,num2= 321 ,num3= undefined
arg[1]= 123 ,arg[2]= 321 ,arg[3]= undefined
Arguments(2) [123, 321, callee: (...), Symbol(Symbol.iterator): ƒ]

change num1 to 0...
change arg[2] to 1...
change arg[3] to 2...

num1= 0 ,num2= 321 ,num3= undefined
arg[1]= 123 ,arg[2]= 1 ,arg[3]= 2
Arguments(2) [123, 1, 2: 2, callee: (...), Symbol(Symbol.iterator): ƒ]

在严格模式下,有名参数与arguments参数互不影响。

一个小小的疑问

在红宝书上说:

...这并不意味着它们都访问同一个内存地址,它们在内存中还是分开的。

我试着修改了一下上面的函数,把传入的参数改为了两个对象,使用严格模式的情况下,我分别对num1和arguments[1]的value属性进行修改,可是结果居然是同步的,输出如下语句,结果为true。

      console.log(arguments[1] === num2);

大概可能说的是这两个变量名在内存中是分开的?只是在传入引用类型之后指向的是同一块地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值