Search code examples
javascriptangularjspass-by-referencepass-by-value

Pass by Value in JSON in angular


I have observed a strange behavior in JSON,

Let me try to describe scenario, we have one angular scope variable say

$scope.regValue = 0;

This is initialized in controller, and used under ngModel in HTML template to track down a change in value.

Now Let's assign this to JSON object key,

var jsonObj = {
  'key1': $scope.regValue
};

What i have observed is, now

jsonObj['key1'] 

value will be 0, which is Correct.

But when ngModel changes the value of $scope.regValue, It is not reflected under JSON key value, which means

jsonObj['key1'] 

is still equal to 0.

While $scope.regValue has already changed.

Is this behavior expected, Or Pass by reference can't pass it's own reference to another variable ?


Solution

  • There is a difference in JavaScript between objects and primitive values (strings, numbers, booleans). Primitives are never passed by reference, while objects always are.

    So in the case of your object property, you are assigning a numeric value to

    var jsonObj = {
      'key1': $scope.regValue // this is a number and assigned as such
    };
    

    When you update a property on the $scope object , you are not modifying the value of the jsonObj variable.

    var $scope = {
      regValue: 0
    }
    
    console.log($scope);
    console.log($scope.regValue);
    
    var jsonObj = {
      key1: $scope.regValue
    }
    
    console.log(jsonObj);
    console.log(jsonObj.key1);
    
    $scope.regValue = 5;
    
    console.log($scope);
    console.log($scope.regValue);
    
    console.log(jsonObj);
    console.log(jsonObj.key1);

    Try this for comparison :

    var otherObject = $scope;
    

    You will see that otherObject reflects all the changes of $scope, because it is actually referencing the same object in memory.

    var $scope = {
      regValue: 0
    }
    
    console.log($scope);
    
    var otherObject = $scope;
    
    $scope.regValue = 5;
    console.log($scope);
    console.log(otherObject);