Javascript AngularJS是交叉绑定变量吗?

Javascript AngularJS是交叉绑定变量吗?,javascript,angularjs,angularjs-scope,angularjs-bindings,Javascript,Angularjs,Angularjs Scope,Angularjs Bindings,我首先使用Promises下载JSON数据并将其存储在变量中: app.controller('mainController', ['$scope', '$http', '$q', function($scope, $http, $q) { var req1 = $http({method: 'GET', url: 'link to JSON 1', cache: 'true'}); var req2 = $http({method: 'GET', url: 'link to JSON

我首先使用Promises下载JSON数据并将其存储在变量中:

app.controller('mainController', ['$scope', '$http', '$q', function($scope, $http, $q) {
  var req1 = $http({method: 'GET', url: 'link to JSON 1', cache: 'true'});
  var req2 = $http({method: 'GET', url: 'link to JSON 2', cache: 'true'});

  $q.all([req1, req2]).then(function(response){
    var res1 = response[0].data;
    var res2 = response[1].data;

    $scope.data1 = res1;       // JSON which I will manipulate
    $scope.data1Ref = res1;   // JSON for reference which I won't manipulate

    $scope.data2 = res2;
    $scope.data2Ref = res2;

    init(); // do the stuff with the data
  });
}]);
但是,在完成
init()
之后,如果我选中
$scope.data1
$scope.data1Ref
,它们都已被修改,也就是说它们被绑定在一起


为什么会发生这种情况?我如何确保保存原始下载的JSON的存储版本以供参考?

当您对对象使用赋值时,您只是给变量一个对象引用,而不是复制对象。在代码中,
$scope.data1
$scope.data1Ref
res1
都指向完全相同的对象实例。要创建新对象,需要复制现有对象

Angular提供了两个可以复制对象的函数,一个创建浅拷贝,另一个创建深拷贝。浅副本复制基本体字段,如果对象包含子对象,则原始和副本都指向同一子对象实例。在深度副本中,任何子对象都会创建新副本


angular.extend
可用于创建浅拷贝,而
angular.copy
可用于深度拷贝。

这是因为在JavaScript中,对象是通过引用传递的。将$scope.data1和$scope.data1Ref设置为res1时,将它们设置为对res1的引用

要解决这个问题,可以使用创建res对象的深度副本

$scope.res1Ref=angular.copy(res1);

在AngularJS中,复杂对象通过引用传递。您可以在这里找到更多信息:

这是因为$scope.data1和$scope.data1Ref引用了res1,所以对res1的任何更改都将反映在这两个参数中。在分配res1之前,您需要复制它。有趣的是,
angular.copy()
似乎比再次下载JSON要花费大量的运行时间(在本例中几乎是4000ms)。因此,至少在本例中,一个潜在的解决方法是下载两次JSON。其他有此问题的人发现了一种更快的克隆算法:而且,lodash有一个深度克隆函数,您可以尝试,uu.cloneDeep()非常感谢您,paulgoblin。使用中的代码可以显著提高性能。