JavaScript 系列 - Arguments 对象

103 阅读2分钟

arguments 是一个对应于传递给函数的参数的类数组对象。

概念

“类数组”意味着 arguments 有长度属性 并且属性的索引是从零开始的,但是它没有 Array的 内置方法

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

arguments[1] = "new value";

属性

  • [arguments.callee]、[arguments.length]、 [arguments[@@iterator]]

    返回一个新的 Array 迭代器对象,该对象包含参数中每个索引的值。

使用示例

转换

  • 添加一个新的元素

    Array.prototype.push

    • 对象本身要可以存取属性
    • 对象的 length 属性可读写
  • 截取一个元素

    Array.prototype.shift

转换为数组使用slice 会有性能问题

  • 通过遍历 arguments 对象来构造一个新的数组
  • 使用 Array 构造函数作为一个函数
var args =
  arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
Array.prototype.slice.call(arguments);
Array.prototype.splice.call(arguments, 0);
Array.prototype.concat.apply([], arguments);
[].slice.call(arguments);

// ES2015
const args = Array.from(arguments);
const args = [...arguments];

遍历参数求和

function add() {
  var sum = 0,
    len = arguments.length;
  for (var i = 0; i < len; i++) {
    sum += arguments[i];
  }
  return sum;
}
add(); // 0
add(1); // 1
add(1, 2, 3, 4); // 10

定义连接字符串的函数

这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串。该函数定义如下:

function myConcat(separator) {
  var args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
}
// returns "red, orange, blue"
myConcat(", ", "red", "orange", "blue");

// returns "elephant; giraffe; lion; cheetah"
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");

// returns "sage. basil. oregano. pepper. parsley"
myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");

定义创建 HTML 列表的方法

这个例子定义了一个函数通过一个字符串来创建 HTML 列表。这个函数唯一正式声明了的参数是一个字符。当该参数为 "u" 时,创建一个无序列表 (项目列表);当该参数为 "o" 时,则创建一个有序列表 (编号列表)。该函数定义如下:

function list(type) {
  var result = "<" + type + "l><li>";
  var args = Array.prototype.slice.call(arguments, 1);
  result += args.join("</li><li>");
  result += "</li></" + type + "l>"; // end list

  return result;
}

你可以传递任意数量的参数到该函数,并将每个参数作为一个项添加到指定类型的列表中。例如:

var listHTML = list("u", "One", "Two", "Three");

/* listHTML is:

"<ul><li>One</li><li>Two</li><li>Three</li></ul>"

*/

剩余参数、默认参数和解构赋值参数

arguments对象可以与剩余参数、默认参数和解构赋值

  • 严格模式相互不会影响
  • 当非严格模式中的
    • 没有使用剩余参数、默认参数和解构赋值,相互影响
    • 使用剩余参数、默认参数和解构赋值,不会相互影响
function foo(...args) {
  return args;
}
foo(1, 2, 3); // [1,2,3]
function foo(name, age, sex, hobbit) {
  console.log(name, arguments[0]); // name name
  // 改变形参
  name = "new name";
  console.log(name, arguments[0]); // new name new name
  // 改变arguments
  arguments[1] = "new age";
  console.log(age, arguments[1]); // new age new age
  // 测试未传入的是否会绑定
  console.log(sex); // undefined
  sex = "new sex";
  console.log(sex, arguments[2]); // new sex undefined
  arguments[3] = "new hobbit";
  console.log(hobbit, arguments[3]); // undefined new hobbit
}

foo("name", "age");