Object creation - Literal or Constructor?

Object creation - Literal or Constructor?

Hi all

I’m work on object creation and inhertiance and I’m trying to work out the best pattern.

I can create an object Literal like this


/*--- Obj-1 ---*/
var Animal_1 = {};

Animal_1.name = 'chris';
Animal_1.getName = function(){
  alert('Name is ' + this.name);
}

Animal_1.getName();

and I can create the same type of obejct with a constructor function


/*--- Obj-2 --*/
function Animal_2(name){
  this.name = name
}

Animal_2.prototype.getName = function(){
  alert('Name is ' + this.name);
}

var tom = new Animal_2('tom');

tom.getName();

My first question is are these two approaches creating the same object. The conctructor approach uses the prototype to create the method. The object Literal approach doesn’t reference the prototype at all. I thought that methods should be placed in the prototype.

Inhertiance

Using the Constructor approach I can create another object that inhertrits from Obj-2


/*--- Obj-3 --*/
function Animal_3(name, mood){
  Animal_2.call(this)
  this.name = name,
  this.mood = mood
}

Animal_3.prototype =  new Animal_2();
Animal_3.prototype.constructor = Animal_3;

var john = new Animal_3('john', 'happy');

john.getName();

alert(john.mood)

How would I create another object that inhertrits using the object Literal approach.

Hi,

In your first example, you are creating a single object and attaching a method to it:

var Animal = {
  name: 'Chris',
  getName: function(){
    console.log('Name is ' + this.name);
  }
};

Animal.getName();
// Name is Chris

If you want lots of animals, you can also write a constructor function to create them for you:

var Animal = function(name){
  this.name = name;

  this.getName = function(){
    return 'Name is ' + this.name;
  };
};

var a = new Animal('Tom'),
    b = new Animal('Jane');

console.log(a.getName());
console.log(b.getName());

// Name is Tom
// Name is Jane

Or you can employ the prototype approach to do the same thing:

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return 'Name is ' + this.name;
}

var c = new Animal('Don'),
    d = new Animal('Sue');

console.log(c.getName());
console.log(d.getName());

// Name is Don
// Name is Sue

The advantage of the second approach is that methods that inherit via the prototype chain can be changed universally for all instances, for example:

function Animal(name){
  this.name = name;
}

Animal.prototype.getName = function(){
  return 'Name is ' + this.name;
}

var a = new Animal('Tom'),
    b = new Animal('Jane');

console.log(a.getName());
console.log(b.getName());

Animal.prototype.getName = function(){
  return "Animals don't have names";
}

console.log(a.getName());
console.log(b.getName()););

// Name is Tom
// Name is Jane
// Animals don't have names
// Animals don't have names

Notice how changing the method applied to both instances? This is because a and b share the same getName() function, whereas c and d have their own, individually created version.

Whereas:

var Animal = function(){
  this.getName = function(){
    return 'Name is ' + this.name;
  };
};

var c = new Animal,
    d = new Animal;

c.name = "Fred",
d.name = "Sue";

console.log(c.getName());
console.log(d.getName());

var Animal = function(){
  this.getName = function(){
    return "Animals don't have names";
  };
};

console.log(c.getName());
console.log(d.getName()

// Name is Fred
// Name is Sue
// Name is Fred
// Name is Sue

Another side effect of creating methods inside the constructor is poorer performance. Each method has to be created every time the constructor function runs.

Methods on the prototype chain are created once and then “inherited” by each instance.

Does that help?

Thanks Pullo, that makes a little more sense now. I think I’ll go with the constructor method