2

I've read extensively about Javascript prototypal inheritance, specifically in child scopes. My understanding is that we always ensure a "." is in our ng-model binding so that it references an object.

My question is ... why does prototypal inheritance create a primitive on its local scope but not an object? It seems like the very same thing.

In one case, we have a primitive. In another case we have an object - say an array. What's even more confusing is that I can pass an object to the child scope (without a ".") and by pushing data onto the object that was passed down within the local scope, the parent object is still modified and thus no child array object is created. Again, why? Prototypal inheritance seems to auto-create primitives ... what makes an object different?

Charles Sounder
  • 591
  • 2
  • 5
  • 16
  • Prototypal inheritance doesn't create anything. Angular adds a property to the current scope. It also doesn't matter if the property is a primitive or an object. – a better oliver Jan 10 '15 at 22:12
  • It does matter. Objects are located on the parent scope and modified appropriately whereas primitives aren't. I'm trying to understand why this is the case. – Charles Sounder Jan 10 '15 at 23:02
  • 1
    Question is far too broad without some examples that may be causing you confusion. I disagree with @zeroflagL though with regard to `doesn't matter` as it sure does matter once scopes get turned into child scopes as to what stays bound and what doesn't – charlietfl Jan 11 '15 at 01:33
  • var $scope.name = "Daniel"; – Charles Sounder Jan 11 '15 at 05:49
  • Charles and @charlietfl, maybe I wasn't explicit enough or misinterpreted the question. The question was: _why does prototypal inheritance create a primitive on its local scope but not an object_. So if you have `ng-model="something.text"` then `text` will be added to `scope.something`. But if the object `something` doesn't already exist somewhere in the scope chain, then **it will be created and added to the current scope**. If you meant something different, Charles, please, rephrase the question. – a better oliver Jan 11 '15 at 08:42
  • I think that what Charles is asking is more a Javascript question than an Angular question. This is how I interpret the question: why a primitive variable is shadowed in the child scope if it's created with the same name as a variable in the parent scope and an object is not shadowed? – ps0604 Jan 11 '15 at 12:36
  • ZeroflagL ... that's exactly my point. Why is it different for primitives? Take your example and apply that logic w/a primitive and you see that it works differently. If I specify a primitive in the child process, it gets created there and thus the parent value isn't used in the child scope. It's the classic ng-model problem in Angular where the child references the parent ... but when you attempt to change the parent, a child gets created. In the case of an object though, the parent is referenced and thus the changes are reflected in both parent and child. – Charles Sounder Jan 11 '15 at 17:51
  • This is due to how prototypal inheritance works in JS. – tasseKATT Jan 12 '15 at 08:35

1 Answers1

1

Here's a simplified (for the example) version of how child scope is created from parent scope. For more comprehensive view - go to the source

Parent scope is created:

function Scope(){ }; 
var scope = new Scope(); // scope instance is created

Suppose it has some primitive and some object properties:

scope.a = 1;
scope.obj = {a: 1};

Child scope instance is created and its prototype is "scope"

function ChildScope(){ };
ChildScope.prototype = scope;
var childScope = new ChildScope(); // an instance of the child scope

Now, let see:

console.log(scope.a);          // should be 1
console.log(childScope.a);     // should be 1
console.log(scope.obj.a);      // should be 1
console.log(childScope.obj.a); // should be 1

As expected, right?

If we now set values on properties exposed in childScope

childScope.a = 2;
childScope.obj.a = 3;

Then here's the output:

console.log(scope.a);          // should still be 1
console.log(childScope.a);     // should be 2 now
console.log(scope.obj.a);      // should be 3
console.log(childScope.obj.a); // should be 3

jsFiddle

So, when you are doing ng-repeat over array of primitives: item in ["a", "b",...] and within it use <input ng-model="item">, you are essentially doing childScope.item = "...".

New Dev
  • 48,427
  • 12
  • 87
  • 129
  • This answer doesn't really explain the _why_ question of the OP, refer to this question for a more extensive answer: http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs?rq=1 – Robin-Hoodie Apr 23 '15 at 06:54
  • The *why* follows from the behavior of prototypical inheritance in JS, and I've showed how a child scope is created with the parent scope as its prototype. That there is a duplicate question and answer is a different story. – New Dev Apr 23 '15 at 11:48