【问题标题】:What's the difference between a regular push and an Array.prototype.push.apply常规推送和 Array.prototype.push.apply 有什么区别
【发布时间】:2016-06-08 21:20:14
【问题描述】:

我不太明白下面两行代码的区别。在我的代码中,带有“应用”的行按我想要的方式工作,而只有常规推送的行却没有。

那么当这两个都被执行时到底发生了什么:

//this one does not work the way i want it to
$scope.items.push(result.data.stuff)

//this one works!
Array.prototype.push.apply($scope.items, result.data.stuff);

编辑:很抱歉造成混淆,我已对其进行了修复,使其具有“推送”方法

【问题讨论】:

  • 有没有“定期推送”的行?是的,我很确定 $cope.items.push(result.data.stuff[0], results.data.stuff[1], …) 会起作用。
  • 抱歉造成混淆...我已修复。请再看推线。

标签: javascript javascript-objects apply


【解决方案1】:

基本区别在Function.prototype.apply()进行了解释。

你可以在那里阅读:

您可以使用 push 将元素附加到数组中。而且,因为推 接受可变数量的参数,您也可以推送多个 元素。

但是,如果你传递一个数组来推送,它实际上会将该数组添加为 单个元素,而不是单独添加元素。所以你 以数组中的数组结束。

所以如果你这样做:

let numbersArray = [1, 2]
numbersArray.push([3, 4])

你将在数组中有一个数组:

[1, 2, [3,4]]

当你有一个想要添加的变量列表时,你可以使用 push.apply()

let numbersArray = [1, 2]
numbersArray.push.apply(numbersArray, [3, 4])

那么你的结果会是这样的:

[1, 2, 3, 4]

【讨论】:

    【解决方案2】:

    见:MDN:Function.prototype.apply();

    请注意本页的注意事项:

    注意:虽然此函数的语法与 call() 的语法几乎相同,但根本区别在于 call() 接受参数列表,而 apply() 接受单个参数数组。

    apply() 方法调用具有给定 this 值的函数,参数作为数组(或类似数组的对象)提供。 argsArray(第二个参数)中的所有项将按顺序用于Array.prototype.push。同理:

    $scope.items.push.apply($scope.items, result.data.stuff);

    因为$scope.items.push === Array.prototype.pushapply() 接受类似数组的参数,但Function.prototype.call() 接受参数列表;

    简而言之,apply 会将类似数组的参数转换为该函数的片段。

    【讨论】:

    • 请将 SO 帖子保持为英文
    • 啊哈!我是新来的,我的英语可能有点差@Bergi
    • 好吧,我们的中文(?)更穷……见meta.stackexchange.com/q/13676/183280
    • 上面的中文是对前面英文的简单描述。
    【解决方案3】:

    新 1. 将数组推送到项目上。

    $scope.items = [1, 2];
    result.data.stuff = [3, 4];
    $scope.items.push(result.data.stuff);
    $scope.items[0] === 1;
    $scope.items[1] === 2;
    $scope.items[2][0] === 3;
    $scope.items[2][1] === 4;
    

    旧 1. 删除 $scope.items 中的现有引用。

    $scope.items = [1, 2];
    result.data.stuff = [3, 4];
    $scope.items = result.data.stuff;
    $scope.items[0] === 3;
    $scope.items[1] === 4;
    

    2。将result.data.stuff 中的所有项目推入$scope.items,保留现有项目。

    $scope.items = [1, 2];
    result.data.stuff = [3, 4];
    Array.prototype.push.apply($scope.items, result.data.stuff);
    $scope.items[0] === 1;
    $scope.items[1] === 2;
    $scope.items[2] === 3;
    $scope.items[3] === 4;
    

    【讨论】:

    • 很抱歉格式错误,似乎有一个降价错误。
    • 或者你只是没有缩进 8 个空格。 ;) 固定
    • @DeepakA 你是什么意思?
    【解决方案4】:

    Array.prototype.push() 是一种将一个或多个元素添加到数组末尾并返回数组新长度的方法。 Array.prototype.push.apply() 获取原始数组和一个包含要添加到原始数组的元素的数组。

    Array.prototype.push() 的示例:

    var numbers = [1, 5, 2, 8];
    numbers.push(3, 4, 6, 7);
    console.log(numbers); // [1, 5, 2, 8, 3, 4, 6, 7]
    

    带有嵌套数组的Array.prototype.push() 示例:

    var foods = [['apples', 'pears']];
    foods.push(['lettuce', 'celery']);
    console.log(foods); // [['apples', 'pears'], ['lettuce', 'celery']]
    

    Array.prototype.push.apply() 的示例:

    var grades = [90, 88, 83, 85];
    var more_grades = [79, 84, 81, 90];
    Array.prototype.push.apply(grades, more_grades);
    console.log(grades); // [90, 88, 83, 85, 79, 84, 81, 90]
    

    带有嵌套数组的Array.prototype.push.apply() 示例:

    var sports = [['running', 'cycling']];
    var other_sports = [['football', 'basketball']];
    Array.prototype.push.apply(sports, other_sports);
    console.log(sports);
    // [['running', 'cycling'], ['football', 'basketball']]
    

    参考资料:

    push

    apply

    【讨论】:

      【解决方案5】:

      我认为 $scope.items = result.data.stuff 不等同于 Array.prototype.push.apply($scope.items, result.data.stuff);

      因为第一个重新分配数组(清除旧元素)

      试试这个:

      $scope.items.push(result.data.stuff[0], result.data.stuff[1], ...);
      

      $scope.items.push.apply($scope.items, result.data.stuff);

      上面就等于调用 Array.prototype.push.apply 因为 $scope.items 是一个数组(我们认为)

      还有一个连接函数:

      $scope.items = $scope.items.concat(result.data.stuff);
      

      【讨论】:

      • 是的,这正是我的意思。 item.push(result.data.stuff)。但它并没有按照我想要的方式工作
      • 我已经更正了: items.push(result.data.stuff) 将整个 result.data.stuff 数组作为一项放入项目中,但 Array.prototype.push.apply 是第二项参数是一个参数数组,以便将每个元素插入 $scope.items。 $scope.items = $scope.items.concat(result.data.stuff);也合并了两个数组
      【解决方案6】:

      push() 将为您传入的每个参数添加一个索引。它不关心它添加到数组中的内容。你告诉添加它的每一个都会将它添加到数组的末尾。

      当您使用apply() 时,它会将您提供的数组作为第二个参数并将其转换为多个参数。 MDN explains it well,不过基本上变成了

      yourArray.push(argument[0],argument[1],argument[2],argument[3]);
      

      【讨论】:

      • 这就是答案。谢谢。
      猜你喜欢
      • 2017-09-19
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多