[].push.apply如何工作?

9
请问有人可以解释一下这行代码是如何工作的吗?
[].push.apply(perms, permutation(arr.slice(0), start + 1, last));

这个函数生成一个输入数组的所有排列组合的数组;

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;
};

你对 apply 方法感兴趣吗?这是你可以调用 JavaScript 方法/函数的一种类型。你可以了解关于 callapply 的知识。也许 https://dev59.com/_nI-5IYBdhLWcg3wKVA9 可以帮助你。 - murli2308
1
具体是什么导致了混淆? - Dave Newton
2个回答

7
[].push 创建一个新的数组,然后获取 push,它与Array.prototype.push相同,但每次都需要创建未使用的对象进行垃圾回收。
如果调用 Array.prototype.push(5) 将不起作用,因为 this 不会设置为一个数组或扩展数组的东西。因此,如果您想将任意函数用作方法,则需要使用 Function.callFunction.applyFunction.bind 来设置 this
如果您有 Array.prototype.push.apply(thisObject, arrArguments),则与 thisObject.push(arrArguments[0], arrArguments[1], ..., arrArguments[n]) 相同,如果 thisObject 在其原型链中具有 push。由于 perms 是一个数组,并且在其自己的原型链中具有 push,因此可以将其替换为:
perms.push.apply(perms, permutation(arr.slice(0), start + 1, last));

使用apply的原因是因为pushpermutations数组的所有内容作为参数传递。因此,如果permutations(....)返回[1,2,3],它就相当于perms.push(1, 2, 3)。你也可以通过为每个元素调用push来编写代码,不使用apply
for (var e of permutation(arr.slice(0), start + 1, last)) {
    perms.push(e);
}

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

perms.push(...permutation(arr.slice(0), start + 1, last))

1

展开后,它与以下内容相同:

Array.prototype.push.apply(arrryToPushTo, ArrayOfItemsToPush)

apply() 来自 Function.prototype.apply()Array.prototype.push 是一个函数。

使用空数组代替写 "Array.prototype" 暴露了可以调用 apply()push() 方法,这样做只是因为 "[]""Array.prototype" 更短。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接