This has nothing to do with Angular. It is plain, old JavaScript-related.
In your fiddle's HTML you have (numbers are for reference below):
(1)<input type="text" ng-model="text1">
(2)<button ng-click="saveText(text1)">Save Text</button>
...
(3)<input type="text" ng-model="textObj.text1">
(4)<input type="text" ng-model="textObj.text2">
(5)<button ng-click="saveObj(textObj)">Save Object Text</button>
The 'string' case (primitive):
Line (1) creates a string variable, named text1
, in InputCtrl's scope (hereafter inScope) and binds it to the value of the input field. Whenever the value of the input field changes, so does the value of inScope.text1
.
When the button (line (2)) is clicked, myService's text
variable is set to the value of inScope.text1
. Because 'string' is a primitive, it is passed by value, meaning that myService.text
and inScope.text1
are not referencing the same object - they just "happen" to have the same value after the saveText()
method is called. Once inScope.text1
changes (e.g. the user types something in the input field), myService.text
knows nothing about it. This case it equivalent to:
var a = 'value1';
var b = a;
// Now: a === 'value1', b === 'value1'
a = 'value2';
// Now: a === 'value2', b === 'value1'
The 'object' case (object):
Lines (3) and (4) create two properties (text1
, text2
) in the (initially empty) object referenced by inScope's textObj
variable. Whenever the value of each input field changes, so does the value of the corresponding property of the object referenced by inScope.textObj
.
When the button (line (5)) is clicked, myService's object
variable is set to reference the same object as inScope.textObj
. You noticed I use the term reference instead of value. Because 'object' is not a primitive, it is passed by reference, meaning that myService.object
and inScope.textObj
are referencing the same object (after the saveObj()
method is called. Changing the values of the input fields defined in lines (2) and (3) affects the properties of the object referenced by inScope.textObj
(which is also referenced by myService.object
). This case it equivalent to:
var a = { key: 'value1' }; // Creates new object, say {obj1}
var b = a; // Now b references {obj1} as well
// Now: a.key === 'value1', b.key === 'value1'
a.key = 'value2'; // Changes {obj1}'s key's value
// but {obj1} is also referenced by b, so...
// Now: a.key === 'value2', b.key === 'value2'
// This does not happen in your code, so you never lose reference to
// the same object from both `myService.object` and `inScope.textObj`
a = { key: 'value3' }; // Creates new object, say {obj2}
// but b still references {obj1}, not {obj2}, so...
// Now: a.key === 'value3', b.key = 'value2'
More info on JS primitives vs objects