2016-06-16 10 views
9

Sto giocando con angular constants. Sto osservando che sono in grado di modificare il valore di constant. Non sono in grado di ottenerlo. Perché sono in grado di cambiare il valore. Sto creando la costante in questo modo:Perché sono in grado di modificare la costante angolare?

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

Anche se creo la costante utilizzando angular.value poi anche io sono in grado di cambiarlo. Per modificare il valore della costante sto facendo questo nel mio controller:

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

Entro la defination di costante quello che ottengo è costante è somehting il cui valore non cambia ed ha un valore fisso. MDN dice che una volta dichiarata la costante non puoi cambiarla se la costante non è un oggetto. per esempio.

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

Ma in caso di costante angolare quando cambio il valore non succede nulla. Non comunica nemmeno che il valore è cambiato. E anche la documentazione non parla della modifica del valore delle costanti. Se possiamo modificare il valore della costante angolare come una semplice variabile javascript, allora perché vengono chiamati costanti? Ecco il fiddle di giocare

+3

Con 'const', l'unica porzione che è" costante "è il riferimento all'oggetto, quindi non è possibile sostituire l'oggetto con un altro. Tuttavia, l'oggetto stesso rimane mutabile e le sue proprietà possono continuare a essere modificate. ['Object.freeze()'] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) renderà l'oggetto immutabile (anche se si noti che non lo fa t farlo in modo ricorsivo). –

+0

Vuoi dire se faccio 'Object.freeze (obj)' allora non sarò in grado di cambiare la proprietà dell'oggetto? Se sì allora perché la squadra angolare non lo sta facendo? Non permetterà a nessuno di cambiare costante. –

risposta

7

C'è una differenza tra:

  • tipi di valore (stringhe, booleani, ecc); e
  • Tipi di riferimento (riferimenti a oggetti, matrici, ecc.);

Una variabile può essere di entrambi i tipi.

variabili costanti sono chiamati "costanti", perché non è possibile modificare il loro contenuti: non è possibile impostare un nuovo valore di riferimento o, rispettivamente.

Inserire in modo diverso, poiché i tipi di riferimento essendo costanti significa che non è possibile modificare quella variabile in modo che faccia riferimento a qualcos'altro. Come si è notato, è possibile modificare il contenuto di qualsiasi oggetto a cui fa riferimento una variabile di riferimento.

Se si vuole fare un oggetto stesso "costante", è possibile utilizzare 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>

noti che Object.freezedoes not do so recursively, avreste bisogno di una funzione/libreria per quello.

Nota anche che ho inserito alcuni commenti su SerialId.Il primo, si rendono conto che ci sono tre cose diverse denominati "SerialId ':

  1. Un angolari nomi costanti' SerialId";
  2. Un argomento di funzione denominato "SerialId";
  3. Il terzo elemento (stringa) nell'array delle dipendenze, "SerialId";

Quando viene eseguita la funzione di costruzione del controllore, l'argomento della funzione verrà riempito con il valore della costante. A proposito, l'argomento della funzione potrebbe essere stato chiamato anche Foo. Si dovrebbe considerare tale argomento come una variabile locale non costante con lo stesso valore della costante.

+1

Ha senso, grazie mille per i chiarimenti. :) –

Problemi correlati