1

When learning angularjs I found out that if you put objects in a prototype object , the instances that inherit from that prototype would change the prototype's objects on assigning.

Example :

function Person(name) {this.name = name;}
Person.prototype = {species : "homo-sapiens" , characteristics : { "legs" : 2 , "height" : 175}}
var joe = new Person("joe"); 
joe.characteristics.legs = 1 ; 
console.log(Person.prototype.characteristics) //Object {legs: 1, height: 175}

What I showed is that the prototype's instance (joe) changed the object's value on the prototype itself because it inherited an object (characteristics) and not a primitive.

My question is as follows : Are prototypes meant most of the time to hold primitives? (in most cases , you would never want an instance to change the prototype's value. Angular.js actually does so , but it's in the rare case where you actually want a child instance to write to the prototype) . And what would you do if you actually wanted to put an object on the prototype without the instances writing to the prototype on assigning?

Joel Blum
  • 7,750
  • 10
  • 41
  • 60
  • Most frameworks that provide "`classes`" provide methods to clone primitives on the prototype to each instance of the `class`. You may want to make a wrapper function for classes if this is desired – megawac Dec 01 '13 at 09:54

2 Answers2

0

This isn't really related to prototype, but just a general JS behavior.

The solution would be to copy the object from the prototype in the constructor,

function Person() {
    this.characteristics = angular.copy(this.characteristics);
}

Person.prototype = { whatever };

The above assumes angular is available for the angular.copy function. Otherwise you would need to manually do a copy of the object by iterating the properties and copying into a new one.

Jani Hartikainen
  • 42,745
  • 10
  • 68
  • 86
0

To get the behavior you're expecting, try this:

function Person(name) {
    this.name = name;
    this.species = "homo-sapiens";  
    this.characteristics = { "legs" : 2 , "height" : 175};
}
// NOTE: line below is no longer needed, but I'm keeping it 
// here just so you can see its output for comparison below
Person.prototype = {species : "homo-sapiens", 
                    characteristics : { "legs" : 2 , "height" : 175}}

var joe = new Person("joe"); 

joe.species = "regular old joe"; 
console.log('Person.prototype.species:', Person.prototype.species); 
// Line above prints: Person.prototype.species: homo-sapiens
console.log('joe.species:', joe.species); 
//joe.species: regular old joe

joe.characteristics.legs = 1 ; 
console.log('Person.prototype.characteristics:', Person.prototype.characteristics); 
//Person.prototype.characteristics: Object {legs: 2, height: 175}
console.log('joe.characteristics:', joe.characteristics); 
//joe.characteristics: Object {legs: 1, height: 175} 

To clarify, your question really has nothing to do with angular, it just has to do with javascript's prototype based inheritance and how it works.

You may want to checkout this article on prototypical inheritance

You may also want to check out this SO question on __proto__ vs prototype.

Community
  • 1
  • 1
Jonah
  • 15,806
  • 22
  • 87
  • 161