먼저 샘플 코드를 살펴보겠습니다
<body ng-app="app"> <div ng-controller="CopyController"> <div> data: <input ng-model="user.data" /><br> user.data: {{user.data}} <br> user1.data: {{user1.data}} <br> <button ng-click="changeData1()">change</button> <br> <button ng-click="copy()">copy</button> <br> copyData: {{copyUser.data}} </div> </div> <script src="node_modules/angular/angular.min.js"></script> </body> <script> angular.module('app', []) .controller('CopyController', function ($scope) { // body... $scope.changeData1 = function () { // body... scope.user1=scope.user1= scope.user; $scope.user1.data = 'is changed'; } $scope.copy = function () { // body... scope.copyUser=angular.copy(scope.copyUser=angular.copy( scope.user); } }); </script>
위 데모에서 볼 수 있듯이 복사 버튼을 클릭하면 copyData의 값은 "this"가 됩니다. is old data", user의 값을 copyUser에 성공적으로 복사했습니다.
변경 버튼을 클릭하면 user1과 user의 값은 'ischanged'로 되지만 copyUser의 값은 복사되지 않았습니다. 변경되었습니다. 이때, 입력 입력란에 값이 변경되면 user와 user1의 값이 그에 따라 변경되어 실제로는 둘이 동일한 변수 참조임을 알 수 있습니다. 그리고 copyUser는 변경되지 않았습니다.
angular.copy가 양방향 바인딩을 취소할 수 있는 원리
이는 JavaScript의 객체가 참조 유형이라는 사실과 관련이 있습니다.
JavaScript의 값 유형
JavaScript에서 값은 기본 값과 참조 값의 두 가지 유형으로 나뉩니다.
기본 값: 스택(Stack)에 저장되는 단순 데이터 필드, 즉 해당 값은 변수에 액세스하는 위치에 직접 저장됩니다.
참조 값: 에 저장됩니다. 힙(heap), 즉 변수에 저장된 값은 객체가 저장된 메모리를 가리키는 포인터입니다.
JavaScript의 객체는 참조 값입니다. 즉, 객체가 참조로 값을 전달한다는 의미입니다.
위 코드에서
$scope.user 및 $scope.user1 개체의 값은 모두 동일한 참조를 가리킵니다. Angular의 경우 변수 변경을 모니터링하는 것은 해당 객체가 참조하는 주소를 모니터링하는 것이므로 객체의 참조 값이 변경되면 이를 가리키는 모든 객체가 그에 따라 변경됩니다.
따라서 Angular에서는 객체 할당을 통해 양방향 바인딩을 직접 해제할 수 없습니다. 따라서 양방향 바인딩을 취소하는 방법은 새 개체를 만든 다음 원래 개체의 값을 새 개체에 할당하는 것입니다. 이것은 JavaScript의 딥 카피가 아닌가?
네, angle.copy는 Angular에서 제공하는 deep copy 방식입니다. 따라서angular.copy를 통해 복사된 객체는 원래 객체 값과 일치할 수 있으며, 이전 객체와 동일한 참조를 가리키지 않으므로 객체 변수의 양방향 바인딩이 구현됩니다.