Js进阶30-类数组对象-arguments

发布时间:2024年01月09日

在 JavaScript 中,arguments 是一个类数组对象,它包含了函数调用时传递给它的所有参数。

这个对象主要用于函数体内,使开发者能够访问和操作调用函数时传入的所有参数。arguments 对象对于理解和使用 JavaScript 函数非常重要,尤其是在处理不确定数量的参数时。

1. 类数组对象

尽管 arguments 看起来像数组,但它并不是真正的数组。它没有数组的方法,如 push、pop 或 slice。如果需要使用这些方法,可以先将 arguments 转换为真正的数组。

function foo() {
  // 类数组对象是引用类型数据
  console.log(typeof arguments); // object
  console.log(arr instanceof Array); // false
  // 数组方法都不能使用
  // arguments.pop(); // TypeError: arguments.pop is not a function
}
foo(1, 2, 3, 4, 5);
function foo() {
  // arguments 对象转换为数组
  // 1. 使用 Array.from() 方法
  let arr1 = Array.from(arguments);
  console.log(arr1); // [ 1, 2, 3, 4, 5 ]
  console.log(typeof arr1); // object
  console.log(arr1 instanceof Array); // true
  console.log(arr1.pop()); // 5
  // 2. 使用 Array.prototype.slice.call() 方法
  let arr2 = Array.prototype.slice.call(arguments);
  console.log(arr2); // [ 1, 2, 3, 4, 5 ]
  console.log(typeof arr2); // object
  console.log(arr2 instanceof Array); // true
  console.log(arr2.pop()); // 5
  // 3. 使用扩展运算符
  let arr3 = [...arguments];
  console.log(arr3); // [ 1, 2, 3, 4, 5 ]
  console.log(typeof arr3); // object
  console.log(arr3 instanceof Array); // true
  console.log(arr3.pop()); // 5

}
foo(1, 2, 3, 4, 5);

2. 包含所有参数

无论函数定义时声明了多少参数,arguments 对象都包含了每个调用该函数时传入的参数。

function foo() {
  // 类数组对象是引用类型数据
  console.log(arguments); // [Arguments] { '0': 1, '1': 'abc', '2': true, '3': null, '4': undefined }
}
foo(1, "abc", true, null, undefined);

3. 索引访问

可以通过索引访问 arguments 中的元素,也可以通过 length 属性获取参数数量,就像在数组中一样。例如,arguments[0] 是第一个参数,arguments[1] 是第二个参数,依此类推。

function foo() {
  console.log(arguments); // [Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5
  console.log(arguments[3]); // 4
  console.log(arguments.length); // 5
}
foo(1, 2, 3, 4, 5);

4. 函数作用域内有效

arguments 对象只在函数体内部有效。它是每个函数作用域内的特殊对象。

5. 与箭头函数的兼容性

在箭头函数中,arguments 对象不可用。箭头函数不绑定自己的 arguments 对象;如果在箭头函数内部使用 arguments,它将取得包含箭头函数的普通函数的 arguments 值。

function outerFunction() {
  let arrowFunction = () => {
    console.log('arguments inside arrow function:', arguments[0]); // arguments inside arrow function: 10
  };

  arrowFunction(20);
}

outerFunction(10);

在这个例子中,outerFunction 是一个普通函数,它定义了一个箭头函数 arrowFunction。当 outerFunction 被调用时,它将一个值传递给 arguments 对象。由于箭头函数没有自己的 arguments 对象,它将访问 outerFunction 的 arguments 对象。

6. callee 属性

arguments.callee 是一个指向当前执行的函数的引用。这在匿名函数中特别有用,因为它允许函数引用自身。

// 阶乘函数
let factorial = function(n) {
    if (n <= 1) return 1;
    return n * arguments.callee(n - 1);
};

console.log(factorial(5)); // 120

这里 arguments.callee 指向当前执行的函数(即匿名函数),用于递归计算阶乘。

7. 修改参数值

在非严格模式下,修改 arguments 对象中的值将影响到对应的命名参数。即如果函数定义了形参,并且你修改了 arguments 中的相应项,那么形参的值也会改变,反之亦然。

function modifyArguments(a, b) {
    arguments[0] = 3;
    arguments[1] = 2;
    console.log(a, b); // 输出: 3 2
}

modifyArguments(1, 1);

在这个示例中,修改 arguments 对象中的值也会改变对应的命名参数。?

8. 不支持严格模式

在严格模式(‘use strict’)下,arguments 对象的行为会有所不同。在严格模式中,修改 arguments 对象中的值不会影响到对应的命名参数。

'use strict';

function modifyArguments(a, b) {
    arguments[0] = 3;
    arguments[1] = 2;
    console.log(a, b); // 输出: 1 1
}

modifyArguments(1, 1);

在严格模式下,修改 arguments 对象不会影响到命名参数。

9. arguments 和 ES6 的 Rest 参数

在 ES6 中,引入了 rest 参数(…args),它提供了一种更清晰、更直接的方式来处理不定数量的参数。相比之下,rest 参数是一个真正的数组,不仅包含 length 属性,还支持数组的所有方法。

function exampleWithRest(...args) {
  args.forEach((arg, index) => {
    console.log('Argument ' + index + ': ' + arg); // Argument 0: hello, Argument 1: world, Argument 2: 42
  });
}

exampleWithRest('hello', 'world', 42);

这里使用 Rest 参数来处理不定数量的参数。Rest 参数是一个真正的数组,支持所有数组方法,提供了更好的语法清晰度。

文章来源:https://blog.csdn.net/m0_57521762/article/details/135468278
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。