2016-06-16 8 views
9

私はangular constantsで遊んでいます。 constantの値を変更できることを確認しています。私はそれを得ることができません。なぜ私は値を変更することができます。私はこのような定数を作成しています:なぜ角度定数を変更できるのですか?

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

私もその後、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); 
}]); 

を、一定のdefinationことで、私が取得することは一定であることは、その値は変更されませんsomehtingあり、それは一定の値を持ちます。 MDNは、定数を宣言すると、定数がオブジェクトでない場合は変更できないと言います。例えば。

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

ただし、値を変更する角度定数の場合は何も起こりません。値が変更されたことを通知することさえありません。また、定数の値を変更することについてのドキュメントもありません。 プレーンなjavascript変数のような角定数の値を変更できるのであれば、なぜそれを定数といいますか?はここに違いあります

+3

'const'では、"定数 "の唯一の部分はオブジェクトへの参照なので、オブジェクトを別のものに置き換えることはできません。ただし、オブジェクト自体は変更可能なままであり、そのプロパティは引き続き変更できます。 ['Object.freeze()'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)は、オブジェクトを不変にします(ただし、再帰的に行う)。 –

+0

'Object.freeze(obj)'を実行すると、オブジェクトのプロパティを変更できなくなりますか?はいの場合、なぜ角チームはそれをやっていないのですか?誰もが変わらないようにします。 –

答えて

7

を再生するためにfiddleです:

  • 値型(文字列、ブール値、など)は、および
  • 参照型(オブジェクト、配列などへの参照)。

変数はいずれのタイプでもかまいません。あなたはそのコンテンツを変更することはできませんので

定数変数は「定数」と呼ばれている:あなたは、それぞれ、新しい値または参照を設定することはできません。

言い換えれば、参照型が定数であることは、その変数を変更して他のものを参照することができないことを意味します。 あなたが指摘したように、は、参照変数が指すオブジェクトの内容を変更します。あなたがしたい場合は

オブジェクト自体が "定数"、あなたはObject.freeze使用することができます:Object.freezedoes not do so recursivelyは、あなたが機能/ライブラリが必要だろう

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>

に留意されたいです。それのために。

また、私は約SerialIdについてのいくつかのコメントでうんざりしていることに注意してください。まずアップ、「SerialId 『という3つの異なるものがあることを実感:

  1. 角度定数名』 SerialId」は、
  2. "SerialId"という名前の関数引数。
  3. 依存配列の3番目の項目(文字列) "SerialId";

コントローラのコンストラクタ関数を実行すると、関数の引数は定数の値で埋められます。関数の引数の名前はFooでも可能です。その引数は、ローカル変数の定数ではなく、定数と同じ値を持つ変数と考えるべきです。

+1

説明のために非常に感謝しています。 :) –

関連する問題