angularjs scope inheritence primitive object

JavaScript Prototypal Inheritance

It is important to first have a solid understanding of JavaScript prototypal inheritance, especially if you are coming from a server-side background and you are more familiar with classical inheritance. So let’s review that first.

Suppose parentScope has properties aString, aNumber, anArray, anObject, and aFunction. If childScope prototypically inherits from parentScope, we have:

normal prototypal inheritance

(Note that to save space, I show the anArray object as a single blue object with its three values, rather than an single blue object with three separate gray literals.)

If we try to access a property defined on the parentScope from the child scope, JavaScript will first look in the child scope, not find the property, then look in the inherited scope, and find the property. (If it didn’t find the property in the parentScope, it would continue up the prototype chain… all the way up to the root scope). So, these are all true:

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

Suppose we then do this:

childScope.aString = 'child string'

The prototype chain is not consulted, and a new aString property is added to the childScope. This new property hides/shadows the parentScope property with the same name. This will become very important when we discuss ng-repeat and ng-include below.

shadowing

Suppose we then do this:

childScope.anArray[1] = '22'
childScope.anObject.property1 = 'child prop1'

The prototype chain is consulted because the objects (anArray and anObject) are not found in the childScope. The objects are found in the parentScope, and the property values are updated on the original objects. No new properties are added to the childScope; no new objects are created. (Note that in JavaScript arrays and functions are also objects.)

follow the chain

Suppose we then do this:

childScope.anArray = [100, 555]
childScope.anObject = { name: 'Mark', country: 'USA' }

The prototype chain is not consulted, and child scope gets two new object properties that hide/shadow the parentScope object properties with the same names.

not following the chain

Takeaways:

  • If we read childScope.propertyX, and childScope has propertyX, then the prototype chain is not consulted.
  • If we set childScope.propertyX, the prototype chain is not consulted.

One last scenario:

delete childScope.anArray
childScope.anArray[1] === 22  // true

We deleted the childScope property first, then when we try to access the property again, the prototype chain is consulted.

after deleting a property

Here is a jsfiddle where you can see the above javascript prototypical inheritance examples being modified and their result (open up your browser’s console to see the output. The console output can be viewed as what the ‘RootScope’ would see).

Angular Scope Inheritance

The contenders:

  • The following create new scopes, and inherit prototypically: ng-repeat, ng-include, ng-switch, ng-view, ng-controller, directive with scope: true, directive with transclude: true.
  • The following creates a new scope which does not inherit prototypically: directive withscope: { ... }. This creates an “isolate” scope instead.

Note, by default, directives do not create new scope — i.e., the default is scope: false.

ng-include

Suppose we have in our controller:

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

And in our HTML:

<script type="text/ng-template" id="/tpl1.html">
    <input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div>

<script type="text/ng-template" id="/tpl2.html">
    <input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

Each ng-include generates a new child scope, which prototypically inherits from the parent scope.

ng-include

Typing (say, “77”) into the first input textbox causes the child scope to get a new myPrimitive scope property that hides/shadows the parent scope property of the same name. This is probably not what you want/expect.

ng-include primitive

Typing (say, “99”) into the second input textbox does not result in a new child property. Because tpl2.html binds the model to an object property, prototypal inheritance kicks in when the ngModel looks for object myObject — it finds it in the parent scope.

ng-include object

We can rewrite the first template to use $parent, if we don’t want to change our model from a primitive to an object:

<input ng-model="$parent.myPrimitive">

Typing (say, “22”) into this input textbox does not result in a new child property. The model is now bound to a property of the parent scope (because $parent is a child scope property that references the parent scope).

ng-include $parent

For all scopes (prototypal or not), Angular always tracks a parent-child relationship (i.e., a hierarchy), via scope properties $parent, $$childHead and $$childTail. I normally don’t show these scope properties in the diagrams.

For scenarios where form elements are not involved, another solution is to define a function on the parent scope to modify the primitive. Then ensure the child always calls this function, which will be available to the child scope due to prototypal inheritance. E.g.,

// in the parent scope
$scope.setMyPrimitive = function(value) {
    $scope.myPrimitive = value;
}

Here is a sample fiddle that uses this “parent function” approach. (This was part of a Stack Overflow post.)

See also http://stackoverflow.com/a/13782671/215945 and
https://github.com/angular/angular.js/issues/1267.

ng-switch

ng-switch scope inheritance works just like ng-include. So if you need 2-way data binding to a primitive in the parent scope, use $parent, or change the model to be an object and then bind to a property of that object. This will avoid child scope hiding/shadowing of parent scope properties.

See also AngularJS, bind scope of a switch-case?

ng-repeat

Ng-repeat works a little differently. Suppose we have in our controller:

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]

And in our HTML:

<ul><li ng-repeat="num in myArrayOfPrimitives">
       <input ng-model="num"></input>
    </li>
</ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
       <input ng-model="obj.num"></input>
    </li>
</ul>

For each item/iteration, ng-repeat creates a new scope, which prototypically inherits from the parent scope, but it also assigns the item’s value to a new property on the new child scope. (The name of the new property is the loop variable’s name.) Here’s what the Angular source code for ng-repeat actually is:

childScope = scope.$new(); // child scope prototypically inherits from parent scope ...     
childScope[valueIdent] = value; // creates a new childScope property

If item is a primitive (as in myArrayOfPrimitives), essentially a copy of the value is assigned to the new child scope property. Changing the child scope property’s value (i.e., using ng-model, hence child scope property num) does not change the array the parent scope references. So in the first ng-repeat above, each child scope gets a num property that is independent of the myArrayOfPrimitives array:

ng-repeat primitive

This ng-repeat will not work (like you want/expect it to). In Angular 1.0.2 or earlier, typing into the textboxes changes the values in the gray boxes, which are only visible in the child scopes. In Angular 1.0.3+, typing into the text boxes has no effect. (See Artem’s explanation as to why on StackOverflow.) What we want is for the inputs to affect the myArrayOfPrimitives array, not a child scope primitive property. To accomplish this, we need to change the model to be an array of objects.

So, if item is an object, a reference to the original object (not a copy) is assigned to the new child scope property. Changing the child scope property’s value (i.e., using ng-model, hence obj.num) does change the object the parent scope references. So in the second ng-repeat above, we have:

ng-repeat object

(I colored one line gray just so that it is clear where it is going.)

This works as expected. Typing into the textboxes changes the values in the gray boxes, which are visible to both the child and parent scopes.

See also Difficulty with ng-model, ng-repeat, and inputs and
ng-repeat and databinding

ng-view

TBD, but I think it acts just like ng-include.

ng-controller

Nesting controllers using ng-controller results in normal prototypal inheritance, just like ng-include and ng-switch, so the same techniques apply. However, “it is considered bad form for two controllers to share information via $scope inheritance” —http://onehungrymind.com/angularjs-sticky-notes-pt-1-architecture/ A service should be used to share data between controllers instead.

(If you really want to share data via controllers scope inheritance, there is nothing you need to do. The child scope will have access to all of the parent scope properties. See also Controller load order differs when loading or navigating)

directives

  1. default (scope: false) – the directive does not create a new scope, so there is no inheritance here. This is easy, but also dangerous because, e.g., a directive might think it is creating a new property on the scope, when in fact it is clobbering an existing property. This is not a good choice for writing directives that are intended as reusable components.
  2. scope: true – the directive creates a new child scope that prototypically inherits from the parent scope. If more than one directive (on the same DOM element) requests a new scope, only one new child scope is created. Since we have “normal” prototypal inheritance, this is like ng-include and ng-switch, so be wary of 2-way data binding to parent scope primitives, and child scope hiding/shadowing of parent scope properties.
  3. scope: { ... } – the directive creates a new isolate/isolated scope. It does not prototypically inherit. This is usually your best choice when creating reusable components, since the directive cannot accidentally read or modify the parent scope. However, such directives often need access to a few parent scope properties. The object hash is used to set up two-way binding (using ‘=’) or one-way binding (using ‘@’) between the parent scope and the isolate scope. There is also ‘&’ to bind to parent scope expressions. So, these all create local scope properties that are derived from the parent scope. Note that attributes are used to help set up the binding — you can’t just reference parent scope property names in the object hash, you have to use an attribute. E.g., this won’t work if you want to bind to parent property parentProp in the isolated scope: <div my-directive> and scope: { localProp: '@parentProp' }. An attribute must be used to specify each parent property that the directive wants to bind to: <div my-directive the-Parent-Prop=parentProp> and scope: { localProp: '@theParentProp' }.
    Isolate scope’s __proto__ references a Scope object. Isolate scope’s $parent references the parent scope, so although it is isolated and doesn’t inherit prototypically from the parent scope, it is still a child scope.
    For the picture below we have
    <my-directive interpolated="{{parentProp1}}" twowayBinding="parentProp2"> and
    scope: { interpolatedProp: '@interpolated', twowayBindingProp: '=twowayBinding' }
    Also, assume the directive does this in its linking function: scope.someIsolateProp = "I'm isolated"
    isolate scope
    One final note: use attrs.$observe('attr_name', function(value) { ... }) in the linking function to get the interpolated value of isolate scope properties that use the ‘@’ notation. E.g., if we have this in the linking function —attrs.$observe('interpolated', function(value) { ... })value would be set to 11. (scope.interpolatedProp is undefined in the linking function. In contrast,scope.twowayBindingProp is defined in the linking function, since it uses the ‘=’ notation.)
    For more information on isolate scopes see http://onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope/
  4. transclude: true – the directive creates a new “transcluded” child scope, which prototypically inherits from the parent scope. So if your transcluded content (i.e., the stuff that ng-transclude will be replaced with) requires 2-way data binding to a primitive in the parent scope, use $parent, or change the model to be an object and then bind to a property of that object. This will avoid child scope hiding/shadowing of parent scope properties.
    The transcluded and the isolated scope (if any) are siblings — the $parent property of each scope references the same parent scope. When a transcluded and an isolate scope both exist, isolate scope property $$nextSibling will reference the transcluded scope.
    For more information on transcluded scopes, see AngularJS two way binding not working in directive with transcluded scope
    For the picture below, assume the same directive as above with this addition:transclude: true
    transcluded scope

This fiddle has a showScope() function that can be used to examine an isolate scope and its associated transcluded scope. See the instructions in the comments in the fiddle.

Summary

There are four types of scopes:

  1. normal prototypal scope inheritance — ng-include, ng-switch, ng-controller, directive with scope: true
  2. normal prototypal scope inheritance with a copy/assignment — ng-repeat. Each iteration of ng-repeat creates a new child scope, and that new child scope always gets a new property.
  3. isolate scope — directive with scope: {...}. This one is not prototypal, but ‘=’, ‘@’, and ‘&’ provide a mechanism to access parent scope properties, via attributes.
  4. transcluded scope — directive with transclude: true. This one is also normal prototypal scope inheritance, but it is also a sibling of any isolate scope.

For all scopes (prototypal or not), Angular always tracks a parent-child relationship (i.e., a hierarchy), via properties $parent and $$childHead and $$childTail.

Diagrams were generated with GraphViz “*.dot” files, which are on github. Tim Caswell’s“Learning JavaScript with Object Graphs” was the inspiration for using GraphViz for the diagrams.

The above was originally posted on StackOverflow.

Advertisements

prototype vs __proto__ in js

short version

__proto__ is the actual object that is used in the lookup chain to resolve methods, etc. prototypeis the object that is used to build __proto__ when you create an object with new

 

long version

prototype is a property of a Function object. It is the prototype of objects constructed by that function.

__proto__ is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O) method, though de facto standard __proto__ is quicker.

 

longer version

prototype is used by constructor() functions. It should’ve really been called something like, "prototypeToInstall", since that’s what it is.

and __proto__ is that “installed prototype” on an object (that was created/installed upon the object from said constructor() function)

 

longest version (from here)

Prerequisite: Understanding JavaScript Objects

Before diving into this post on prototypes, it will be helpful if you have a basic understanding of what objects are in JavaScript, how they work, and how to create them. If you aren’t familiar with these concepts, I highly recommend you read my post on Understanding JavaScript Objects.

In Understanding JavaScript Objects, I used the following examples of creating objects:

Example A

var catA = {name: "Fluffy", color: "White", age: 0};

Example B

var catB = Object.create(new Object());
catB.name = "Fluffy";
catB.color = "White";
catB.age = 0;

Example C

function Cat(name, color) {
  this.name = name;
  this.color = color;
}
Cat.prototype.age = 0;

var catC = new Cat("Fluffy", "White");

In these examples, A and B produce identical results while example C produces a something different. Example B is not very commonly used since Example A is much less verbose and equally useful. While example A is very common and quite useful, it doesn’t apply much to this blog post so I will be almost solely working with example C, which uses function Cat, for the remainder of this post.

Why is Cat a function instead of a class?

We know from Understanding JavaScript Objects that Cat is a constructor function. A constructor function really is no different than any other function, in fact the term “constructor function” is just a common nomenclature that suggests that the function will create properties on the object being created (represented by this). In other words, when we say var catC = new Cat("Fluffy", "White"), all that really is happening is the catC object is created and assigned to this for the duration of the call to the Cat function. Therefore, inside the function, this.name = name; is the same as sayingcatC.name = name. Hopefully, that helps to clarify that constructor functions are not doing anything magic, they are just normal functions that are creating properties on this — even though we use them in a way that is similar to how classes work in other languages. In fact, using the new keyword, you can create an object out of any function (it just doesn’t make sense with other functions).

Cat.prototype.age? What’s that all about?

Ok, first of all, notice that Cat.prototype.age isn’t really part of the Cat function. It’s also helpful to realize when this code gets executed. Seeing the code all lumped together like that might fool you into thinking thatCat.prototype.age = 0; is being called when a new cat is created, which of course, on closer inspection is obviously not true. Usually this code (including the creation of the Cat function above it) is called when a web page is first loaded; thus making the Cat function available to be called. So think about what is happening there. The Cat function is being created and then the age property is being created (with a value of 0) on the Cat function’s prototype.

Wait, functions have a prototype? What’s a prototype?

Functions can be used to create class-like functionality in JavaScript; and all functions have a prototype property. That prototype property is somewhat like a class definition in other object-oriented langauge; but it is more than that. It is actually an instance of an object and every function in JavaScript has one whether you use it or not. Every function (constructor function or not) has a prototype object instance hanging off of it, interesting, huh?

So, let’s talk about how this prototype object is actually used. When you create an object using the new keyword, it creates a new object, passes it in as this to the constructor function (letting that function do to it whatever it wants) and then, and this is the important part, it takes the object instance that is pointed to by that function’s prototype property and assigns it as the prototype for that object.

So objects have a prototype property too?

Well, yes but you don’t access it the same way and it isn’t used for the same purpose as a function’s prototype. And this is where a lot of confusion usually begins with prototypes (don’t worry if your confusion began long before this, that’s normal too). Objects do not have a prototype property, but they do have a prototype. Only, the word prototype means something different when talking about objects than it does when talking about functions. It would be nice if we had a different word, for now, let’s call it proto (you’ll understand why in a minute). So functions have prototypes and objects have protos. They are very similar, in fact, a function’s prototype and an object’s proto often (in fact, usually) point to the same object in memory.

An object’s proto is the object from which it is inheriting properties. Notice I said it is the object from which it is inheriting properties, not the function orclass, it really is an object instance in memory. This differs from a function’s prototype which is used as the object to be assigned as the proto for new objects’ created using this function as a constructor function. An object’s proto can be retrieved by calling myObject.__proto__ in most browsers (thanks IE) and by calling Object.getPrototypeOf(myObject) in all browsers — I’ll use __proto__ going forward for simplicity.

So let’s give an actual definition to each of these terms:

  • A function’s prototype: A function’s prototype is the object instance that will become the prototype for all objects created using this function as a constructor.
  • An object’s prototype: An object prototype is the object instance from which the object is inherited.

Back to the examples

All that explanation can be confusing without showing some examples, so let’s dive in. If you inspect the prototype of the cats in Examples A and B you get the following result:

catA.__proto__;
Object { }

But, if you inspect the cat in Example C you get this result:

catC.__proto__;
Cat {age: 0}

Side note: I am using chrome’s developer console to execute these statements and I will be displaying the results shown by chrome in grey textas shown above.

Note that in examples A and B, they do have a prototype (__proto__) even though they were not created using a constructor function. Since we didn’t specify a prototype for these, they have a prototype of Object. It is possible to create objects without a prototype using this syntax: var myObject = Object.create(null);, but that is very rare and I’ve never seen a use for it. So barring that example, I think it is safe to say that all objects eventually inherit from Object.

This is even true of catC; look what happens when we inspect catC further:

catC.__proto__;
Cat {age: 0}

catC.__proto__.__proto__;
Object { }

catC.__proto__.__proto__.__proto__;
null

Notice that catC has a prototype (__proto__) of Cat. Actually, to say it that way is not really accurate. Cat is a function, so it cannot be a prototype; remember in the definitions above that a prototype is not a function it is anobject instance. This is important to remember when thinking about prototypes — an object’s prototype is not the function that created it but an instance of an object. Since this is important, let’s explore it a bit further:

Cat;
function Cat(name, color) {
  this.name = name;
  this.color = color;
}

Cat.prototype;
Cat {age: 0}

catC;
Cat {name: "Fluffy", color: "White", age: 0}

Look at the difference between Cat, Cat.prototype and catC. What this is showing is that Cat is a function but Cat.prototype and catC are objects. It further shows that Cat.prototype has an age property (set to 0) and catC has three properties — including age…sort of (stay tuned). When you define a function, it creates more than just the function, it also creates a new objectwith that function as it’s type and assigns that new object to the function’s prototype property. When we first created the Cat function, before we executed the line Cat.prototype.age = 0;, if we would have inspected Cat’s prototype it would have looked like this: Cat {}, an object with no properties, but of type Cat. It was only after we called Cat.prototype.age = 0; that it looked like this: Cat {age: 0}.

Inherited properties vs. native properties

In the above paragraph, I stated that catC had “three properties — including age…sort of (stay tuned)”…thanks for sticking with me. Age really isn’t a direct property of catC. You can see this by executing these statements:

catC.hasOwnProperty("name");
true

catC.hasOwnProperty("color");
true

catC.hasOwnProperty("age");
false

This is because age, actually belongs to catC’s prototype; and yet, if I execute the statement catC.age;, it does indeed return 0. What is actually happening here, is when we ask for catC.age, it checks to see if catC has a property named age, and if it does it returns it, if not, it asks catC’s prototype if it has an age property. It continues doing this all the way up the prototype chain until it finds the matching property or finds an object with a null prototype and if it doesn’t find the property in the prototype chain it will return undefined.

So that’s what prototype chaining is?

Yep. You may have heard of prototype chaining before. It is really quite simple to understand now that you (hopefully) understand a little more about how prototypes work. A prototype chain is basically a linked-list of objects pointing backwards to the object from which each one inherits.

Changing an function’s prototype

Remember that a function’s prototype is just an object, so what would happen if we started changing the properties of a function’s prototype after we created objects from it? Consider the following examples:

function Cat(name, color) {
  this.name = name;
  this.color = color;
}
Cat.prototype.age = 3;

var fluffy = new Cat("Fluffy", "White");
var scratchy = new Cat("Scratchy", "Black");

fluffy.age;
3

scratchy.age;
3

Cat.prototype.age = 4;

fluffy.age;
4

scratchy.age;
4

So, notice that changing the age of the Cat function’s prototype property also changed the age of the cats that had inherited from it. This is because when the Cat function was created so was it’s prototype object; and every object that inherited from it inherited this instance of the prototype object as their prototype. Consider the following example:

function Cat(name, color) {
  this.name = name;
  this.color = color;
}
Cat.prototype.age = 3;

var fluffy = new Cat("Fluffy", "White");
var scratchy = new Cat("Scratchy", "Black");

fluffy.age;
3

scratchy.age;
3

Cat.prototype = {age: 4};

fluffy.age;
3

scratchy.age;
3

var muffin = new Cat("Muffin", "Brown");

muffin.age;
4

First, notice that I did not just change the value of the prototype.age property to 4, I actually changed the Cat function’s prototype to point to a new object. So while Muffin inherited the new prototype object, Fluffy’s and Scratchy’s prototypes are still pointing to their original prototype object, which they originally inherited from the Cat function. This illustrates the point that a function’s prototype property “is the object instance which will become the prototype (or __proto__) for objects created using this function as a constructor.”

One more example to illustrate this point. What would happen if I changed the value of the age property of fluffy’s prototype? Would this be different than simply changing fluffy’s age? Yes, it would be different. Think about the examples above, and about how age is not actually a property on fluffy, it is a property of fluffy’s prototype.

So, given this setup:

function Cat(name, color) {
  this.name = name;
  this.color = color;
}
Cat.prototype.age = 3;

var fluffy = new Cat("Fluffy", "White");
var scratchy = new Cat("Scratchy", "Black");

Compare this example:

fluffy.age = 4;

fluffy.age;
4

scratchy.age;
3

To this example:

fluffy.__proto__.age = 4;

fluffy.age;
4

scratchy.age;
4

These produce different results because in the first example, we are just adding a new age property to the fluffy. So in the first example both fluffy and fluffy.__proto__ have age properties with the vales 4 and 3, respectively. When you ask for fluffy.age, it finds the property on the fluffy object so returns it immediately without ever looking up the prototype chain.

Whereas in the second example, fluffy still does not have an age property, but it’s prototype (which is the same instance in memory as scratchy’s prototype) now has a the new value 4 thus affecting both fluffy’s and scratchy’s ages.

Multiple Levels of Inheritance

I have to confess, this is not something I use often because I tend to prefer composition over inheritance; but that is not to say it is without a place. Say you want to create a constructor function that “inherits” from another constructor function, much like you would do in other languages when you create one class that inherits from another. Let’s look at an example of how you may do this:

function Animal(name) {
  this.name = name;
}
Animal.prototype.age=1;

function Cat(name, color) {
  Animal.call(this, name);
  this.color = color;
}
Cat.prototype = new Animal(null);

var catC = new Cat("Fluffy", "White");

catC.name;
Fluffy

catC.color;
White

catC.age;
1

catC.hasOwnProperty("name");
true

catC.hasOwnProperty("color");
true

catC.hasOwnProperty("age");
false

Notice that age is the only property that is not a direct property of catC. This is because when we called the Cat constructor function, it passed in our new object (catC/this) to the Animal function which created the name property on the object. The Cat function then also added the color property to catC/this. But the age property was added to the Animal function’s prototype, it was never added directly to catC.

Inheriting Functions

In all the examples above, I used properties like name, color, and age to illustrate objects and inheritance. However, everything that I have done above with properties can be done with functions. If we were to create a speak() function on the Cat Function like this: Cat.prototype.speak = function() { alert('meow'); };, that function would be inherited by all objects that have Cat as their prototype, just like with the name, color and age properties.

 

 

 

 

Public/Private Variables and Methods in javascript

Summary

  • private variables are declared with the ‘var’ keyword inside the object, and can only be accessed by private functions and privileged methods.
  • private functions are declared inline inside the object’s constructor (or alternatively may be defined via var functionName=function(){...}) and may only be called by privileged methods (including the object’s constructor).
  • privileged methods are declared with this.methodName=function(){...} and may invoked by code external to the object.
  • public properties are declared with this.variableName and may be read/written from outside the object.
  • public methods are defined by Classname.prototype.methodName = function(){...} and may be called from outside the object.
  • prototype properties are defined by Classname.prototype.propertyName = someValue
  • static properties are defined by Classname.propertyName = someValue

Example

In this example, a person’s name and race are set at birth and may never be changed. When created, a person starts out at year 1 and a hidden maximum age is determined for that person. The person has a weight which is modified by eating (tripling their weight) or exercising (halfing it). Every time the person eats or exercises, they grow a year older. The person object has a publicly accessible ‘clothing’ property which anyone can modify, as well as a dirtFactor which can be modified manually (throwing dirt on or scrubbing it off), but which increases every time the person eats or exercises, and is reduced by the use of the shower() method.

 

The Example Code

function Person(n,race){ 
	this.constructor.population++;

	// ************************************************************************ 
	// PRIVATE VARIABLES AND FUNCTIONS 
	// ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
	// *********************************************************************** 
	var alive=true, age=1;
	var maxAge=70+Math.round(Math.random()*15)+Math.round(Math.random()*15);
	function makeOlder(){ return alive = (++age <= maxAge) } 

	var myName=n?n:"John Doe";
	var weight=1;


	// ************************************************************************ 
	// PRIVILEGED METHODS 
	// MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
	// MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
	// ************************************************************************ 
	this.toString=this.getName=function(){ return myName } 

	this.eat=function(){ 
		if (makeOlder()){ 
			this.dirtFactor++;
			return weight*=3;
		} else alert(myName+" can't eat, he's dead!");
	} 
	this.exercise=function(){ 
		if (makeOlder()){ 
			this.dirtFactor++;
			return weight/=2;
		} else alert(myName+" can't exercise, he's dead!");
	} 
	this.weigh=function(){ return weight } 
	this.getRace=function(){ return race } 
	this.getAge=function(){ return age } 
	this.muchTimePasses=function(){ age+=50; this.dirtFactor=10; } 


	// ************************************************************************ 
	// PUBLIC PROPERTIES -- ANYONE MAY READ/WRITE 
	// ************************************************************************ 
	this.clothing="nothing/naked";
	this.dirtFactor=0;
} 


// ************************************************************************ 
// PUBLIC METHODS -- ANYONE MAY READ/WRITE 
// ************************************************************************ 
Person.prototype.beCool = function(){ this.clothing="khakis and black shirt" } 
Person.prototype.shower = function(){ this.dirtFactor=2 } 
Person.prototype.showLegs = function(){ alert(this+" has "+this.legs+" legs") } 
Person.prototype.amputate = function(){ this.legs-- } 


// ************************************************************************ 
// PROTOTYOPE PROERTIES -- ANYONE MAY READ/WRITE (but may be overridden) 
// ************************************************************************ 
Person.prototype.legs=2;


// ************************************************************************ 
// STATIC PROPERTIES -- ANYONE MAY READ/WRITE 
// ************************************************************************ 
Person.population = 0;



// Here is the code that uses the Person class 
function RunGavinsLife(){ 
	var gk=new Person("Gavin","caucasian");       //New instance of the Person object created. 
	var lk=new Person("Lisa","caucasian");        //New instance of the Person object created. 
	alert("There are now "+Person.population+" people");

	gk.showLegs(); lk.showLegs();                 //Both share the common 'Person.prototype.legs' variable when looking at 'this.legs' 

	gk.race = "hispanic";                         //Sets a public variable, but does not overwrite private 'race' variable. 
	alert(gk+"'s real race is "+gk.getRace());    //Returns 'caucasian' from private 'race' variable set at create time. 
	gk.eat(); gk.eat(); gk.eat();                 //weight is 3...then 9...then 27 
	alert(gk+" weighs "+gk.weigh()+" pounds and has a dirt factor of "+gk.dirtFactor);

	gk.exercise();                                //weight is now 13.5 
	gk.beCool();                                  //clothing has been update to current fashionable levels 
	gk.clothing="Pimp Outfit";                    //clothing is a public variable that can be updated to any funky value 
	gk.shower();
	alert("Existing shower technology has gotten "+gk+" to a dirt factor of "+gk.dirtFactor);

	gk.muchTimePasses();                          //50 Years Pass 
	Person.prototype.shower=function(){           //Shower technology improves for everyone 
		this.dirtFactor=0;
	} 
	gk.beCool=function(){                         //Gavin alone gets new fashion ideas 
		this.clothing="tinfoil";
	};

	gk.beCool(); gk.shower();
	alert("Fashionable "+gk+" at " 
		+gk.getAge()+" years old is now wearing " 
		+gk.clothing+" with dirt factor " 
		+gk.dirtFactor);

	gk.amputate();                                //Uses the prototype property and makes a public property 
	gk.showLegs(); lk.showLegs();                 //Lisa still has the prototype property 

	gk.muchTimePasses();                          //50 Years Pass...Gavin is now over 100 years old. 
	gk.eat();                                     //Complains about extreme age, death, and inability to eat. 
}

Notes

  • maxAge is a private variable with no privileged accessor method; as such, there is no way to publicly get or set it.
  • race is a private variable defined only as an argument to the contructor. Variables passed into the constructor are available to the object as private variables.
  • The ‘tinfoil’ beCool() fashion method was applied only to the gk object, not the entire Person class. Other people created and set to beCool() would still use the original ‘khakis and black shirt’ clothing that Gavin eschewed later in life.
  • Note the implicit call to the gk.toString() method when using string concatenation. It is this which allows the code alert(gk+' is so cool.') to put the word ‘Gavin’ in there, and is equivalent to alert(gk.toString()+' is so cool.'). Every object of every type in JS has a .toString() method, but you can override it with your own.
  • You cannot (to my knowledge) assign public methods of a class inside the main object constructor…you must use the prototype property externally, as above with the beCool()and shower() methods.
  • As I attempted to show with the Person.prototype.legs property and the amputate() function, prototype properties are shared by all object instances. Asking for lk.legsyields ‘2’ by looking at the single prototype property. However, attempting to change this value using either gk.legs=1 or (in the Person object) this.legs=1 ends up making a new public property of the object specific to that instance. (This is why calling gk.amputate() only removed a leg from Gavin, but not Lisa.) To modify a prototype property, you must use Person.prototype.legs=1 or something like this.constructor.prototype.legs=1. (I say ‘something like’ because I discovered thatthis.constructor is not available inside private functions of the object, since this refers to the window object in that scope.)
  • Wherever an anonymous function is declared inline with
    foo = function(p1,p2){ some code }
    the new Function() constructor is NOT equivalent, e.g.
    foo = new Function('p1','p2','code');
    since the latter runs in the global scope–instead of inheriting the scope of the constructor function–thus preventing it from accessing the private variables.
  • As noted above in the code comments, the act of setting gk.race to some value did NOT overwrite the private race variable. Although it would be a dumb idea, you can have both private and public variables with the same name. For example, the yell() method in the following class will yield different values for foo and this.foo:
    function StupidClass(){ 
      var foo = "internal";
      this.foo = "external";
      this.yell=function(){ alert("Internal foo is "+foo+"\nExternal foo is "+this.foo) } 
    }
  • Private functions and privileged methods, like private variables and public properties, are instantiated with each new object created. So each time new Person() is called, new copies of makeOlder()toString()getName()eat()exercise()weigh()getRace()getAge(), and muchTimePasses() are created. For every Person,each time. Contrast this with public methods (only one copy of beCool() and shower() exist no matter how many Person objects are created) and you can see that for memory/performance reasons it can be preferable to give up some degree of object protection and instead use only public methods.Note that doing so requires making private variables public (since without privileged accessor methods there would be no way to use them) so the public methods can get at them…and which also allows external code to see/destroy these variables. The memory/performance optimization of using only public properties and methods has consequences which may make your code less robust.For example, in the above age and maxAge are private variables; age can only be accessed externally through getAge() (it cannot be set) and maxAge cannot be read or set externally. Changing those to be public properties would allow any code to do something like gk.maxAge=1; gk.age=200; which not only does it not make sense (you shouldn’t be able to manipulate someone’s age or lifespan directly), but by setting those values directly the alive variable wouldn’t properly be updated, leaving your Person object in a broken state.

Just think of constructor functions as classes and the properties of the prototype (ie of the object referenced by the constructor function’s prototype property) as shared members, ie members which are the same for each instance. In class-based systems, methods are implemented the same way for each instance, so methods are normally added to the prototype, whereas an object’s fields are instance-specific and therefore added to the object itself during construction.

 

Good explaination about prototype

Spring Bean Scopes

When defining a <bean> in Spring, you have the option of declaring a scope for that bean. For example, To force Spring to produce a new bean instance each time one is needed, you should declare the bean’s scope attribute to be prototype. Similar way if you want Spring to return the same bean instance each time one is needed, you should declare the bean’s scope attribute to be singleton.

The Spring Framework supports following five scopes, three of which are available only if you use a web-aware ApplicationContext.

Scope Description
singleton This scopes the bean definition to a single instance per Spring IoC container (default).
prototype This scopes a single bean definition to have any number of object instances.
request This scopes a bean definition to an HTTP request. Only valid in the context of a web-aware Spring ApplicationContext.
session This scopes a bean definition to an HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.
global-session This scopes a bean definition to a global HTTP session. Only valid in the context of a web-aware Spring ApplicationContext.

This chapter will discuss about first two scopes and remaining three will be discussed when we will discuss about web-aware Spring ApplicationContext.

The singleton scope:

If scope is set to singleton, the Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object.

The default scope is always singleton however, when you need one and only one instance of a bean, you can set the scope property to singleton in the bean configuration file, as shown below:

<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
    <!-- collaborators and configuration for this bean go here -->
</bean>

EXAMPLE:

Let us have working Eclipse IDE in place and follow the following steps to create a Spring application:

Step Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Create Java classes HelloWorld and MainApp under the com.tutorialspoint package.
4 Create Beans configuration file Beans.xml under the src folder.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of HelloWorld.java file:

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

Following is the content of the MainApp.java file:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

Following is the configuration file Beans.xml required for singleton scope:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
      scope="singleton">
   </bean>

</beans>

Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:

Your Message : I'm object A
Your Message : I'm object A

The prototype scope:

If scope is set to prototype, the Spring IoC container creates new bean instance of the object every time a request for that specific bean is made. As a rule, use the prototype scope for all state-full beans and the singleton scope for stateless beans.

To define a prototype scope, you can set the scope property to prototype in the bean configuration file, as shown below:

<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
    <!-- collaborators and configuration for this bean go here -->
</bean>

EXAMPLE:

Let us have working Eclipse IDE in place and follow the following steps to create a Spring application:

Step Description
1 Create a project with a name SpringExample and create a package com.tutorialspoint under the src folder in the created project.
2 Add required Spring libraries using Add External JARs option as explained in the Spring Hello World Example chapter.
3 Create Java classes HelloWorld and MainApp under the com.tutorialspoint package.
4 Create Beans configuration file Beans.xml under the src folder.
5 The final step is to create the content of all the Java files and Bean Configuration file and run the application as explained below.

Here is the content of HelloWorld.java file:

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

Following is the content of the MainApp.java file:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

Following is the configuration file Beans.xml required for prototype scope:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
      scope="prototype">
   </bean>

</beans>

Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:

Your Message : I'm object A
Your Message : null