为什么我能改变角度常数?

时间:2022-01-16 21:46:24

I am playing with angular constants. I am observing that I am able to change the value of the constant. I am not able to get it. Why I am able to change the value. I am creating the constant like this:

我正在玩角度常数。我观察到我能够改变常数的值。我无法得到它。为什么我能够改变价值。我正在创建这样的常量:

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

Even if I create the constant using angular.value then also I am able to change it. To change the value of constant I am doing this in my controller:

即使我使用angular.value创建常量,我也能够改变它。要更改常量的值,我在控制器中执行此操作:

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);
}]);

By the defination of constant what I get is constant is somehting whose value does not change and it has a fixed value. MDN says that once you declare the constant you can not change it if constant is not an object. eg.

通过对常数的定义,我得到的是不变的是某些东西,它的值不会改变并且它具有固定值。 MDN说,一旦声明了常量,如果常量不是对象,则无法更改它。例如。

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

But in case of angular constant when I change the value nothing happens. It does not even notify that the value is changed. And there documentation also does not talk about changing the value of constants. If we can change the value of angular constant like a plain javascript variable then why do they are called constants? Here's the fiddle to play

但是在角度不变的情况下,当我改变值时没有任何反应。它甚至没有通知值已更改。并且文档也没有谈论改变常量的值。如果我们可以像普通的javascript变量那样改变角度常量的值那么为什么它们被称为常量?这是小提琴

1 个解决方案

#1


7  

There's a difference between:

两者之间有区别:

  • Value types (strings, booleans, etc); and
  • 值类型(字符串,布尔值等);和
  • Reference types (references to objects, arrays, etc);
  • 引用类型(对对象,数组等的引用);

A variable can be of either type.

变量可以是任何一种类型。

Constant variables are called "constants" because you cannot change their content: you cannot set a new value or reference, respectively.

常量变量称为“常量”,因为您无法更改其内容:您无法分别设置新值或引用。

Put differently, for reference types being constant means you cannot change that variable so that it'll reference something else. As you noted, you can change the contents of whatever object a reference variable points to.

换句话说,对于引用类型是常量意味着您不能更改该变量,以便它引用其他内容。如您所述,您可以更改引用变量指向的任何对象的内容。

If you want to make an object itself "constant", you can use Object.freeze:

如果你想让一个对象本身“常量”,你可以使用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>

Note that Object.freeze does not do so recursively, you'd need a function/library for that.

请注意,Object.freeze不会递归地执行此操作,您需要一个函数/库。

Note also that I snuck in some comments about SerialId. First up, realize that there's three different things named "SerialId":

另请注意,我在窃听有关SerialId的一些评论。首先,要意识到有三个不同的东西叫做“SerialId”:

  1. An angular constant names "SerialId";
  2. 角度常量名称为“SerialId”;
  3. A function argument named "SerialId";
  4. 一个名为“SerialId”的函数参数;
  5. The third item (string) in the dependencies array, "SerialId";
  6. 依赖项数组中的第三项(字符串),“SerialId”;

When the controller constructor function is run, the function argument will be filled with the value from the constant. The function argument could've been named Foo as well, by the way. You should consider that argument to be a local non-constant variable with the same value as the constant has.

运行控制器构造函数时,函数参数将使用常量中的值填充。顺便说一句,函数参数也可以被命名为Foo。您应该将该参数视为局部非常量变量,其值与常量具有相同的值。

#1


7  

There's a difference between:

两者之间有区别:

  • Value types (strings, booleans, etc); and
  • 值类型(字符串,布尔值等);和
  • Reference types (references to objects, arrays, etc);
  • 引用类型(对对象,数组等的引用);

A variable can be of either type.

变量可以是任何一种类型。

Constant variables are called "constants" because you cannot change their content: you cannot set a new value or reference, respectively.

常量变量称为“常量”,因为您无法更改其内容:您无法分别设置新值或引用。

Put differently, for reference types being constant means you cannot change that variable so that it'll reference something else. As you noted, you can change the contents of whatever object a reference variable points to.

换句话说,对于引用类型是常量意味着您不能更改该变量,以便它引用其他内容。如您所述,您可以更改引用变量指向的任何对象的内容。

If you want to make an object itself "constant", you can use Object.freeze:

如果你想让一个对象本身“常量”,你可以使用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>

Note that Object.freeze does not do so recursively, you'd need a function/library for that.

请注意,Object.freeze不会递归地执行此操作,您需要一个函数/库。

Note also that I snuck in some comments about SerialId. First up, realize that there's three different things named "SerialId":

另请注意,我在窃听有关SerialId的一些评论。首先,要意识到有三个不同的东西叫做“SerialId”:

  1. An angular constant names "SerialId";
  2. 角度常量名称为“SerialId”;
  3. A function argument named "SerialId";
  4. 一个名为“SerialId”的函数参数;
  5. The third item (string) in the dependencies array, "SerialId";
  6. 依赖项数组中的第三项(字符串),“SerialId”;

When the controller constructor function is run, the function argument will be filled with the value from the constant. The function argument could've been named Foo as well, by the way. You should consider that argument to be a local non-constant variable with the same value as the constant has.

运行控制器构造函数时,函数参数将使用常量中的值填充。顺便说一句,函数参数也可以被命名为Foo。您应该将该参数视为局部非常量变量,其值与常量具有相同的值。