2016-06-16 22 views
9

Tôi đang chơi với angular constants. Tôi quan sát thấy rằng tôi có thể thay đổi giá trị của constant. Tôi không thể làm được. Tại sao tôi có thể thay đổi giá trị. Tôi đang tạo ra hằng số như sau:Tại sao tôi có thể thay đổi hằng số góc?

var app = angular.module('app', []); 
app.constant('Type', { 
    PNG: 'png', 
    GIF: 'gif' 
}); 
app.constant('serialId', 'aRandomId'); 

Thậm chí nếu tôi tạo hằng số bằng cách sử dụng angular.value thì tôi cũng có thể thay đổi nó. Để thay đổi giá trị của hằng số tôi đang làm điều này trong bộ điều khiển của tôi:

app.controller('MainController', ['$scope', 'Type', 'serialId', '$timeout', function($scope, Type, serialId, $timeout) { 
    $scope.data = { 
    type: Type, 
    serialId: serialId 
    }; 
    $timeout(function() { 
    Type.PNG = 'this is changed'; 
    serialId = 'new Serial Id'; 
    console.log(serialId); 
    }, 1000); 
}]); 

Đến, định nghĩa của liên tục những gì tôi nhận được là không đổi là somehting có giá trị không thay đổi và nó có một giá trị cố định. MDN nói rằng một khi bạn khai báo hằng số bạn không thể thay đổi nó nếu hằng số không phải là một đối tượng. ví dụ.

const x=10; 
x=20;//will throw the error. 
const obj={}; 
obj.a='ab'; //will not throw error. 

Nhưng trong trường hợp hằng số góc khi tôi thay đổi giá trị thì không có gì xảy ra. Nó thậm chí không thông báo rằng giá trị được thay đổi. Và có tài liệu cũng không nói về việc thay đổi giá trị của hằng số. Nếu chúng ta có thể thay đổi giá trị của hằng số góc như một biến javascript đơn giản thì tại sao chúng được gọi là hằng số? Đây là fiddle để chơi

+3

Với 'const', phần duy nhất" liên tục "là tham chiếu đến đối tượng, vì vậy bạn không thể thay thế đối tượng bằng đối tượng khác. Tuy nhiên, bản thân đối tượng vẫn còn có thể thay đổi và các thuộc tính của nó có thể tiếp tục được sửa đổi. ['Object.freeze()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) sẽ làm cho đối tượng bất biến (mặc dù lưu ý rằng nó không ' t làm theo cách đệ quy). –

+0

Bạn có nghĩa là nếu tôi làm 'Object.freeze (obj)' thì tôi sẽ không thể thay đổi thuộc tính của đối tượng? Nếu có thì tại sao nhóm góc cạnh không làm việc đó? Nó sẽ không cho phép bất cứ ai thay đổi liên tục. –

Trả lời

7

Có sự khác biệt giữa:

  • Giá trị các loại (chuỗi, boolean, vv); và
  • Loại tham chiếu (tham chiếu đến đối tượng, mảng, v.v ...);

Biến có thể thuộc một trong hai loại.

biến liên tục được gọi là "hằng số" bởi vì bạn không thể thay đổi họ nội dung: bạn không thể đặt một giá trị mới hoặc tham chiếu, tương ứng.

Đặt khác, đối với các loại tham chiếu là hằng số có nghĩa là bạn không thể thay đổi biến đó để biến sẽ tham chiếu một thứ khác. Như bạn đã lưu ý, bạn có thể thay đổi nội dung của bất kỳ đối tượng nào mà biến tham chiếu trỏ đến.

Nếu bạn muốn làm cho một đối tượng tự "liên tục", bạn có thể sử dụng Object.freeze:

var app = angular.module('app', []) 
 
    .constant('Type', Object.freeze({ PNG: 'png', GIF: 'gif' })) 
 
    .constant('SerialId', 'asdfgh12345') 
 
    .controller('myController', ['$timeout', 'Type', 'SerialId', MyController]); 
 
    
 
function MyController($timeout, Type, SerialId) { 
 
    var vm = this; 
 
    
 
    // This .data property nor its properties are constant or frozen... 
 
    vm.data = { 
 
    type: Type, 
 
    serialId: SerialId 
 
    }; 
 
    
 
    $timeout(function() { 
 
    Type.PNG = 'this is changed in timeout'; 
 
    SerialId = 'changed serial id in timeout'; 
 
    }, 1000); 
 
    
 
    $timeout(function() { 
 
    var el = document.getElementById('x'); 
 
    var injector = angular.element(el).injector(); 
 
    vm.secondData = { 
 
     type: injector.get('Type'), 
 
     serialId: injector.get('SerialId') 
 
    } 
 
    }, 2000); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.js"></script> 
 
<div ng-app="app" ng-controller="myController as vm" id="x"> 
 
    <pre>{{ vm | json }}</pre> 
 
</div>

Lưu ý rằng Object.freezedoes not do so recursively, bạn cần một hàm/thư viện cho điều đó.

Cũng lưu ý rằng tôi đã thu hút một số nhận xét về SerialId.Đầu tiên, hãy nhận ra rằng có ba thứ khác nhau có tên "SerialId":

  1. Tên hằng số góc "SerialId";
  2. Đối số chức năng có tên "SerialId";
  3. Mục thứ ba (chuỗi) trong mảng phụ thuộc, "SerialId";

Khi hàm khởi tạo bộ điều khiển được chạy, đối số hàm sẽ được lấp đầy với giá trị từ hằng số. Đối số chức năng cũng có thể được đặt tên là Foo. Bạn nên xem xét đối số đó là biến số không đổi cục bộ có cùng giá trị với hằng số.

+1

Làm cho cảm giác cảm ơn bạn rất nhiều vì đã làm rõ. :) –

Các vấn đề liên quan