[].push.apply 如何工作?

Dav*_*vis 8 javascript recursion apply

有人可以解释一下这行代码是如何工作的。

[].push.apply(perms, permutation(arr.slice(0), start + 1, last));
Run Code Online (Sandbox Code Playgroud)

此函数生成输入数组的所有排列的数组;

var permutation = function(arr, start, last){
  var length = arr.length;

  if(!start){
    start = 0;
  }

  if(!last){
    last = length - 1;
  }

  if( last === start){
    return [arr];
  }

  var temp;
  var perms = [];

  for(var i = start; i < length; i++){
    swapIndex(arr, i, start);
    console.log(arr);

    [].push.apply(perms, permutation(arr.slice(0), start + 1, last)); 

    swapIndex(arr, i, start);
  }

  return perms;
};
Run Code Online (Sandbox Code Playgroud)

Syl*_*ter 6

[].push创建一个新数组,然后获取push,这Array.prototype.push与每次需要垃圾收集时创建一个未使用的对象相同。

如果你调用Array.prototype.push(5)它不会工作,因为this不会被设置为数组或扩展数组的东西。因此,您需要使用Function.call,Function.applyFunction.bind来设置this是否要使用任意函数作为方法工作。

如果你 Array.prototype.push.apply(thisObject, arrArguments)是一样的 thisObject.push(arrArguments[0], arrArguments[1], ..., arrArguments[n]),如果thisObjectpush在它的原型链。由于perms是一个数组并且push在它自己的原型链中,它可以被替换为:

perms.push.apply(perms, permutation(arr.slice(0), start + 1, last));
Run Code Online (Sandbox Code Playgroud)

使用apply是因为push获取permutations数组的所有内容作为参数。因此,如果permutations(....)返回[1,2,3],它将与perms.push(1, 2, 3). 您可以apply通过调用push每个元素来编写它:

for (var e of permutation(arr.slice(0), start + 1, last)) {
    perms.push(e);
}
Run Code Online (Sandbox Code Playgroud)

在 ES6 中,您可以简单地使用与扩展语法相同apply但更易于理解的语法

perms.push(...permutation(arr.slice(0), start + 1, last))
Run Code Online (Sandbox Code Playgroud)