AngularJS Angular $scopes Avoid inheriting primitive values


Example

In javascript, assigning a non-primitive value (Such as Object, Array, Function, and many more), keeps a reference (an address in the memory) to the assigned value.

Assigning a primitive value (String, Number, Boolean, or Symbol) to two different variables, and changing one, won't change both:

var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6

But with a non-primitive value, since both variables are simply keeping references to the same object, changing one variable will change the other:

var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John

In angular, when a scope is created, it is assigned all of its parent's properties However, changing properties afterwards will only affect the parent scope if it is a non-primitive value:

angular.module('app', [])
.controller('myController', ['$scope', function($scope){
    $scope.person = { name: 'John Doe' }; //non-primitive
    $scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);

<div ng-app="app" ng-controller="myController">
    binding to input works: {{person.name}}<br/>
    binding to input does not work: {{name}}<br/>
    <div ng-controller="myController1">
        <input ng-model="person.name" />
        <input ng-model="name" />
    </div>
</div>

Remember: in Angular scopes can be created in many ways (such as built-in or custom directives, or the $scope.$new() function), and keeping track of the scope tree is probably impossible.

Using only non-primitive values as scope properties will keep you on the safe side (unless you need a property to not inherit, or other cases where you are aware of scope inheritance).