替换数组内容的简短方法

23t*_*tux 6 javascript arrays underscore.js angularjs

有没有方便的方法来替换数组的内容,并保持对它的引用?我不想像这样替换数组:

var arr1 = [1,2,3];
var referenceToArr1 = arr1;
var arr2 = [4,5,6];

arr1 = arr2;
// logs: [4,5,6] false
console.log(arr1, arr1===referenceToArr1);
// logs [1,2,3]
console.log(referenceToArr1);
Run Code Online (Sandbox Code Playgroud)

这种方式arr1有内容arr2,但我放松了参考referenceToArr1,因为它仍然指向原文 arr1.

通过这种方式,我没有放弃参考:

var arr1 = [1,2,3];
var referenceToArr1 = arr1;
var arr2 = [4,5,6];

arr1.length = 0;
for (var i = 0; i < arr2.length; i++) {
  arr1.push(arr2[i]);
}
// logs: [4,5,6] true
console.log(arr1, arr1===referenceToArr1);
// logs: [4,5,6]
console.log(referenceToArr1)
Run Code Online (Sandbox Code Playgroud)

这里的缺点是,我必须清空arr1.length = 0,迭代每个元素arr2arr1手动推送它.

我的问题是:

  • 当然,我可以为此写一个帮手,但最有效的方法是什么?
  • 有没有一个短的,香草的JavaScript方式,这样做(也许是一个班轮?)
  • 我也使用underscore.js但没有找到解决此类问题的方法.有没有办法用underscore.js做到这一点?

背景:

我有一个服务的AngularJS应用程序.在这个服务中,我有一个数组来保持从服务器加载所有元素.来自服务get的数据绑定到控制器并在视图中使用.当来自服务的数据发生变化(例如重新发生)时,我想自动更新我的控制器变量及其绑定的视图.

这是一个Plunker:http://plnkr.co/edit/8yYahwDO6pAuwl6lcpAS?p=preview

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, myService) {
  $scope.name = 'World';
  myService.fetchData().then(function(data) {
    console.log(data)
    $scope.data = data;
  })
});

app.service('myService', function($timeout, $q) {
  var arr;
  var deferred;

  var loadData = function() {
    // here comes some data from the server
    var serverData = [1,2,3];
    arr = serverData;
    deferred.resolve(arr);

    // simulate a refetch of the data
    $timeout(function() {
      var newServerData = [4,5,6];
      // this won't work, because MainCtrl looses it's reference
      // arr = newServerData;
    }, 1000);

    $timeout(function() {
      var newServerData = [7,8,9];
      arr.length = 0;
      [].push.apply(arr, newServerData);
    }, 2000);

    $timeout(function() {
      var newServerData = [10,11,12];
      [].splice.apply(arr, [0, arr.length].concat(newServerData));
    }, 3000);
  }

  return {
    fetchData: function() {
      deferred = $q.defer();

      loadData();

      return deferred.promise;
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

并且观点:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <ul>
      <li ng-repeat="d in data">{{d}}</li>
    </ul>
    3 refetches every second
  </body>

</html>
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 11

那这个呢:

// 1. reset the array while keeping its reference
arr1.length = 0;
// 2. fill the first array with items from the second
[].push.apply(arr1, arr2);
Run Code Online (Sandbox Code Playgroud)

看到:

  1. 如何在JavaScript中清空数组?
  2. .push()多个对象进入JavaScript数组返回'undefined'


Den*_*ret 6

您可以使用splice将以下内容之一替换arr1arr2

[].splice.apply(arr1, [0, arr1.length].concat(arr2));
Run Code Online (Sandbox Code Playgroud)

这样,所有对它的引用arr1将被正确更新,因为这将是具有新内容的同一数组。

如您所见,这是可能且容易的。但是通常没有理由在设计良好的程序中执行此操作。如果原因是要将数组传递到不同的位置,那么也许应该考虑将此数组嵌入对象中。