为什么以及何时使用angular.copy? (深度复制)

我一直保存从服务接收的所有数据直接到本地variables,控制器或范围。 我认为会被认为是浅拷贝,这是正确的吗?

Example: DataService.callFunction() .then(function(response) { $scope.example = response.data; }); 

最近我被告知要使用angular.copy来创build一个深层副本。

 $scope.example = angular.copy(response.data); 

但是,当我的Angular应用程序使用深度复制信息时,似乎也是以相同的方式工作的。 使用深层拷贝(angular.copy)有什么特别的好处,你可以向我解释一下吗?

在将对象或数组的值分配给另一个variables时使用angular.copy ,并且不应更改该object值。

没有深拷贝或使用angular.copy ,更改属性的值或添加任何新的属性更新引用同一对象的所有对象。

 var app = angular.module('copyExample', []); app.controller('ExampleController', ['$scope', function($scope) { $scope.printToConsole = function() { $scope.main = { first: 'first', second: 'second' }; $scope.child = angular.copy($scope.main); console.log('Main object :'); console.log($scope.main); console.log('Child object with angular.copy :'); console.log($scope.child); $scope.child.first = 'last'; console.log('New Child object :') console.log($scope.child); console.log('Main object after child change and using angular.copy :'); console.log($scope.main); console.log('Assing main object without copy and updating child'); $scope.child = $scope.main; $scope.child.first = 'last'; console.log('Main object after update:'); console.log($scope.main); console.log('Child object after update:'); console.log($scope.child); } } ]); // Basic object assigning example var main = { first: 'first', second: 'second' }; var one = main; // same as main var two = main; // same as main console.log('main :' + JSON.stringify(main)); // All object are same console.log('one :' + JSON.stringify(one)); // All object are same console.log('two :' + JSON.stringify(two)); // All object are same two = { three: 'three' }; // two changed but one and main remains same console.log('main :' + JSON.stringify(main)); // one and main are same console.log('one :' + JSON.stringify(one)); // one and main are same console.log('two :' + JSON.stringify(two)); // two is changed two = main; // same as main two.first = 'last'; // change value of object's property so changed value of all object property console.log('main :' + JSON.stringify(main)); // All object are same with new value console.log('one :' + JSON.stringify(one)); // All object are same with new value console.log('two :' + JSON.stringify(two)); // All object are same with new value 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="copyExample" ng-controller="ExampleController"> <button ng-click='printToConsole()'>Explain</button> </div> 

在这种情况下,你不需要使用angular.copy()

说明

  • =表示一个引用,而angular.copy()创build一个新的对象作为深层副本。

  • 使用=意味着改变response.data的属性会改变$scope.example的相应属性,反之亦然。

  • 使用angular.copy()这两个对象将保持独立,变化不会相互反映。

我会说angular.copy(source); 在你的情况是不必要的,如果以后你不使用它没有一个目的地angular.copy(source, [destination]);

如果提供了一个目的地,那么它的所有元素(对于数组)或属性(对于对象)都将被删除,然后将所有来自源的元素/属性复制到它。

https://docs.angularjs.org/api/ng/function/angular.copy

我只是在这里分享我的经验,我用angular.copy()比较两个对象的属性。 我正在处理一些没有表单元素的input,我想知道如何比较两个对象的属性,并根据结果我必须启用和禁用保存button。 所以我使用如下。

我分配了一个原始的服务器对象用户值到我的虚拟对象说userCopy,并用手表来检查用户对象的变化。

我的服务器API,它从服务器获取我的数据

 var req = { method: 'GET', url: 'user/profile/'+id, headers: {'Content-Type': 'application/x-www-form-urlencoded'} } $http(req).success(function(data) { $scope.user = data; $scope.userCopy = angular.copy($scope.user); $scope.btnSts=true; }).error(function(data) { $ionicLoading.hide(); }); 

/ /最初我的保存button被禁用,因为对象是相同的,一旦//更改我正在保存btn

 $scope.btnSts=true; $scope.$watch('user', function(newVal, oldVal){ console.log($scope.userCopy.name); console.log(); if ($scope.userCopy.name !== $scope.user.name || $scope.userCopy.email !== $scope.user.email ) { console.log('changed'); $scope.btnSts=false; }else{ console.log('unchanged'); $scope.btnSts=true; } }, true); 

我不确定,但是比较两个对象总是对我非常头疼,但是angular.copy()却变得非常糟糕。

使用angular.copy时,不是更新引用,而是创build一个新对象并将其分配给目标(如果提供了目标)。 但还有更多。 有一个很酷的事情发生在深拷贝之后。

假设你有一个工厂服务,它具有更新工厂variables的方法。

 angular.module('test').factory('TestService', [function () { var o = { shallow: [0,1], // initial value(for demonstration) deep: [0,2] // initial value(for demonstration) }; o.shallowCopy = function () { o.shallow = [1,2,3] } o.deepCopy = function () { angular.copy([4,5,6], o.deep); } return o; }]); 

以及使用该服务的控制器,

 angular.module('test').controller('Ctrl', ['TestService', function (TestService) { var shallow = TestService.shallow; var deep = TestService.deep; console.log('****Printing initial values'); console.log(shallow); console.log(deep); TestService.shallowCopy(); TestService.deepCopy(); console.log('****Printing values after service method execution'); console.log(shallow); console.log(deep); console.log('****Printing service variables directly'); console.log(TestService.shallow); console.log(TestService.deep); }]); 

当上面的程序运行时,输出如下,

 ****Printing initial values [0,1] [0,2] ****Printing values after service method execution [0,1] [4,5,6] ****Printing service variables directly [1,2,3] [4,5,6] 

因此,使用angular度复制的好处是,目标的引用会随着值的变化而反映出来,而不必手动重新赋值。

JavaScript通过by reference传递variables,这意味着:

 var i = []; var j = i; i.push( 1 ); 

现在因为by reference部分i是[1],并且j也是[1],即使只有i被改变了。 这是因为当我们说j = i JavaScript不复制ivariables,并将其分配给j但通过j引用ivariables。

angular度复制让我们失去了这个参考,这意味着:

 var i = []; var j = angular.copy( i ); i.push( 1 ); 

现在i在这里等于[1],而j仍然等于[]。

有些情况下,这种copyfunction非常方便。