0

So I've been trying to figure out prototypal inheritance in Javascript and I'm still confused on one point. Let's say I want to make a constructor function for a person with a few functions of it's own.

function Person(name) {
  this.name = name;
  this.sayName = function() {
    console.log("My name is " + name);
  }
}

var john = new Person("John");

john.sayName();

So in this case I've created an object and called a function, however this doesn't seem to be the efficient way to do it. Another example I've seen this is this:

function Person(name) {
  this.name = name;
}
Person.prototype.sayName = function() {
  console.log("My name is " + name);
}

var john = new Person("John");

john.sayName();

Now I've read that the second object is more efficient because it's not storing the sayName function within itself, instead it's going up the prototype chain until it finds it within Persons prototype object.

What I'm unsure about is which I should use for complicated constructor functions. The first snippet, in my opinion, is much much easier to read than the second because there is a clear hierarchical structure to it, but the second snippet is supposedly more efficient.

In a real world scenario, which style of constructor function would I be more likely to use?

Edit: I have a follow up question. Is there any way to make the second snippet more readable?

Mike
  • 3
  • 3
  • 2
    **Second**, consider if you want to create 1000 users. And the first _can_ be used in singleton classes(only once initialised, single object). – Tushar Oct 17 '15 at 07:20
  • Depends on the number of instances you intend to create. If it is a one off object with only one instance, the first method is fine. If not, you'll unnecessarily be storing multiple instances of the same member function inside each instance. – techfoobar Oct 17 '15 at 07:22
  • try to stick with functions on the prototype – Saar Oct 17 '15 at 07:23
  • In you post the second is better. But currently the best approach is of course **ES6 class**. If you need backward compatibility, use **babel**. – Leo Oct 17 '15 at 07:36
  • It always depends on what you want to achieve. The first is ok for singletons. – webduvet Oct 17 '15 at 08:09

4 Answers4

0

if you use the first one , you'll be creating a new function object for sayName each time the constructor is called, while in the second way you avoid that overhead.

if you use a reference type in your constructor it will be shared, for ex :

    function Person(name){
    this.name = name;
    this.hobbies = [..some hobbies];
}

now hobbies will be shared by every object you create with this constructor , so it's best to put shared properties on prototype and only use unique one's in the constructor

Ramanlfc
  • 8,283
  • 1
  • 18
  • 24
0

Generally if you are going to have a class from which several instances will be created, you should add the methods to the prototype object. The main reason I believe is that all the instances of a class would reference the prototype object, and won't copy it. So if the prototype object changes, it would be reflected in the prototype object referenced by all the instances.

This is better than the first option where each method is created (copied) on each instance. And so a lot of instances would also mean a lot of those methods will be created, occupying memory. But in the second option, they all use the single method created on the prototype object.

Samuel Imolorhe
  • 664
  • 4
  • 10
0

In the first approach will create method function for every single instance. In the second one, all instances share the method defined in the prototype. So the second approach is better because of saving memory.

However, ECMAScript 6 is officially released several months ago, so why not try class:

class Person {
  constructor(name) {
    this.name = name;
  }

  sayName() {
    console.log("My name is " + this.name);
  }
}

var john = new Person("John");
john.sayName(); // "My name is John"

The feature is not well supported yet, if you want backward compatibility in browsers, use Babel.

Leo
  • 13,428
  • 5
  • 43
  • 61
0

Another syntax introduced in ECMAScript 5 for create instances of Classes is:

Object.create(prototype [, propertiesObject ] )

Example:

var MyClass = function (param) {
    this.field1 = param;
}
MyClass.prototype.changeField = function(param){
    this.field1 = param;
}
var instance = Object.create(MyClass.prototype);

If you are interested in learn advanced things about javascript I suggest a book called "Mastering Javascript design patterns".

Luis Carlos
  • 345
  • 3
  • 10