与 arguments 基础

非箭头函数的其他函数的内置的局部变量

  • 对象
  • 函数内部对应参数的实参列表对象
  • 内置局部变量


本质是类数组对象 Array-like

  • length 属性
  • 从 0 开始的属性下标
  • 没有数组的内置方法
    • build-in methods / object 内置方法
    • internal methods 内部方法 ```javascript function test(a, b, c) { console.log(arguments); // Arguments[1,2,3] console.log(arguments.toString()); // [object Arguments] console.log(Array.isArray(arguments)); // false console.log(arguements.callee); // function test }

test(1, 2, 3);

  1. callee 宿主函数<br />Symbol(Symbol.iterator) 可迭代对象标志
  2. 对于箭头函数
  3. ```javascript
  4. var test = (...args) => {
  5. console.log(argumenets); // 报错 arguments is not defined
  6. console.log(args); // [1, 2, 3] 把形参实参通过剩余参数的方式相统一
  7. console.log(Array.isArray(args)); // true
  8. }
  9. test(1, 2, 3);

为什么在 ES6 中要弱化 arguments

  1. 在实践中,发现 argumenets 很少不用于非数组的方法
  2. 直接使用函数名,比调用 arguements.callee 宿主函数更快(直接引用),且浏览器可以优化,免去 . 指针解释的操作。这也是在严格模式中,禁用 callee 的原因。

而 arguement 比数组现在就多了 callee。所以 ES6 觉得没有必要用 arguments,而使用剩余参数,得出参数的数组

arguments 转数组

function test(a, b, c) {
  var argArr = [].slice.call(arguments);
  console.log(argArr);
}

test(1, 2, 3);

slice 用在 arguments 身上会阻止 JS 引擎(V8) 做一些特定的优化

以下为解决的方法

function test(a, b, c) {
  var argArr = [];

  for (var v of arguments){
      argArr.push(v);
  } 
}
function test(a, b, c) {
  var argArr = arguments.length === 1 ? [arguments[0]] 
           : Array.apply(null, arguments);
}

arguments 的使用

  1. 实参个数大于形参个数
  2. 不定参数

最大的用途是保存实参,本来就是实参列表

function test(a, b, c){
    console.log(arguments[3]); // 4
}

test(1,2,3,4)

在不定参时使用

function test(){
    console.log(arguments[3]); // 4
}

test(1,2,3,4)

arguments 会被处理 (可修改)

function test(a, b, c){
    for(var i = 0; i < arguments.length; i++){
      arguments[i] += 1;
  }

  console.log(arguments); // Arguments {0:2, 1:3, 2:3, 3:4, length:4}
}

test(1,2,3,4)

形实参数对应关系 (共享关系)

形实参默认情况下会有共享关系

function test(a){
    arguments[0] = 10;
  console.log(a, arguments[0]); // 10 10
}
test(1)


function test2(a){
    a = 100;
  console.log(a, arguments[0]); // 100 100
}
test2(2)

弱化 arguments 对应关系

ES5 和 ES6 都在不断地弱化 arguments 对应关系

形参中但凡有一个参数有默认值,arguments 都 不会对应跟踪参数最终的值

function test(a = 100){
    arguments[0] = 10;
  console.log(a, arguments[0]); // 1 10
}

test(1);

function test2(a = 100){
    a = 1000
  console.log(a, arguments[0]); // 1000 1
}

test2(1);

function test(a, b, c = 10){
  arguments[0] = 100;
  arguments[1] = 200;
  arguments[2] = 300;

  console.log(a, arguments[0]); // 1 100
  console.log(b, arguments[1]); // 2 200
  console.log(c, arguments[2]); // 3 300
}

test(1, 2, 3);

使用剩余参数符,也不会跟踪参数最终的值

function test(...args){
  arguments[0] = 100;
  arguments[1] = 200;
  arguments[2] = 300;

  console.log(args[0], arguments[0]); // 1 100
  console.log(args[1], arguments[1]); // 2 200
  console.log(args[2], arguments[2]); // 3 300
}

test(1, 2, 3);

参数解构也不跟踪

function test({a, b, c}){
  arguments[0] = 100;
  arguments[1] = 200;
  arguments[2] = 300;

  console.log(a, arguments[0]); // 1 100
  console.log(b, arguments[1]); // 2 200
  console.log(c, arguments[2]); // 3 300
}

test({
    a: 1,
  b: 2,
  c: 3
});

严格模式,形实参在 arguments 实参参数表中不作对应关系
并且去掉 arguments.callee

function test(a, b, c){
  'use strict';

  a = 10;
  b = 20;
  c = 30;

  console.log(a, b, c); // 10 20 30
  console.log(arguments); // Arguemtns[1, 2, 3]
}

test(1, 2, 3);


function test2(a, b, c){
  'use strict';

  arguments[0] = 10;
  arguments[1] = 20;
  arguments[2] = 30;

  console.log(a, b, c); // 1 2 3
  console.log(arguments); // Arguemtns[10, 20, 30]

  console.log(arguments); // 报错
}

test2(1, 2, 3);