首先我們來看看範例程式碼
<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>
從上面的示範可以看到,當點擊copy按鈕時,copyData的值就變成了”this is old data”,成功將user的值複製到copyUser.
當點擊change按鈕後,user1和user的值都變成了'is changed',而copyUser的值卻沒有發生改變。這時候在input輸入框改變值,user和user1的值都會跟著改變,說明了這二者實際上是同一個變數引用。而copyUser沒有發生變化。
angular.copy 能取消雙向繫結的原理
這跟JavaScript中對象是參考型別有關。
JavaScript中的實值型別
在JavaScript中,值分為原始值和引用值兩種類型。
原始值:儲存在棧(Stack)中的簡單資料欄位,也就是說,它們的值是直接儲存在變數訪問的位置;
引用值:儲存在堆(heap)中,也就是說,儲存在變數處的值是一個指標,指向儲存物件的記憶體處。
如下圖所示:
在JavaScript中的對象便是引用值,也就是說對象是通過引用傳遞值的。
所以在上述的代碼中:
對象$scope.user和$scope.user1的值都是指向了同一個引用。對於Angular來說,監聽變數變化是在監聽其對象所引用的地址,所以當對象的引用值發生了變化,所有指向它的對象都會跟著發生變化。
所以在Angular中,直接通過對象的賦值是無法解除雙向繫結的。所以要想解除雙向繫結的辦法就是新建立個對象,然後將原有的對象的值賦值給新對象。這不就是JavaScript中的深拷貝嘛。
對的,angular.copy就是Angular提供的 deep copy 的方法。所以通過angular.copy複製出來的對象,既能和原有的對象值保持一致,又不與舊對象指向同一個引用,從而實現瞭解除物件變數的雙向繫結。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者使用Angular.js能有所協助,如果有疑問大家可以留言交流。