Array.prototype.slice.apply(arguments)

使用 slice 和 apply 将 arguments 转换为真正的数组

问题

解释 Array.prototype.slice.apply(arguments) 的作用和实现原理。

解答

这段代码的目的是将类数组对象 arguments 转换为真正的数组。

arguments 是函数内部的特殊对象,它看起来像数组(有 length 属性和索引),但并不是真正的数组,因此无法直接使用数组的方法如 slicemapfilter 等。

通过 apply 方法,可以借用数组的 slice 方法来处理 arguments

function example() {
  // arguments 是类数组对象
  console.log(Array.isArray(arguments)); // false
  
  // 转换为真正的数组
  var args = Array.prototype.slice.apply(arguments);
  console.log(Array.isArray(args)); // true
  
  // 现在可以使用数组方法
  args.forEach(function(item) {
    console.log(item);
  });
}

example(1, 2, 3);

slice() 方法会创建数组的浅拷贝,当不传参数时,会复制整个数组。applyarguments 作为 this 传给 slice,实现了类数组到数组的转换。

现代 JavaScript 有更简洁的方式:

// ES6 扩展运算符
var args = [...arguments];

// Array.from
var args = Array.from(arguments);

关键点

  • arguments 是类数组对象,不是真正的数组,无法直接使用数组方法
  • slice() 可以实现数组的浅拷贝,不传参数时复制整个数组
  • apply 改变 slicethis 指向,使其作用于 arguments
  • ES6 提供了更简洁的转换方式:扩展运算符和 Array.from()