7

JavaScript objects have the 'prototype' member to facilitate inheritance. But it seems, we can live perfectly well, even without it, and I wondered, what are the benefits of using it. I wondered what are the pros and cons.

For example, consider the following (here jsfiddle):

function Base (name) {

    this.name = name;
    this.modules = [];
    return this;
}

Base.prototype =
{
    initModule: function() {
        // init on all the modules.
        for (var i = 0; i < this.modules.length; i++)
            this.modules[i].initModule();
        console.log("base initModule");
    }   
};

function Derived(name) {
       Base.call(this,name); // call base constructor with Derived context
}

Derived.prototype = Object.create(Base.prototype);

Derived.prototype.initModule = function () {
      console.log("d init module");
      //  calling base class functionality
      Base.prototype.initModule.call(this);
    }

var derived = new Derived("dname");
console.log(derived.name);
derived.initModule();

A question is, why use 'prototype' at all? We can also do something like Derived = Object.create(Base);

for example (jsfiddle):

Base =
{
    initModule: function() {
        // init on all the modules.
        for (var i = 0; i < this.modules.length; i++)
            this.modules[i].initModule();
        console.log("base initModule",this.name);
    },
    init: function(name) {
        this.name = name; 
        this.modules = [];
    }
};

Derived = Object.create(Base);

Derived.initModule = function () {
      console.log("d init module");
      //  calling base class functionality
      Base.initModule.call(this);
    }
Derived.init("dname");
console.log(Derived.name);
Derived.initModule();
3
  • 3
    One pro is speed: jsperf.com/prototype-vs-non-prototype/11 Commented Mar 7, 2013 at 16:16
  • what if you have 4 level on inheritance ? you'll declare a newnewnewInitModule method ? Commented Mar 7, 2013 at 16:24
  • @mpm you are right, was a mistake, I edited this away Commented Mar 7, 2013 at 16:43

3 Answers 3

3

If you don't use the prototype, the methods are redefined with every class. That is to say, new Base; new Base; new Base will create six functions in the second example. This takes more time and space. Derived will also create its own functions.

Additionally, you can't use the prototype to change methods for each instance on the fly (or add new methods), which could be potentially helpful -- especially across modules.

However that's not to say that you should always use the prototype for every method. Each situation is different.

prototype also allows you to call methods in a different context without creating an instance (as in the case of Array.prototype.forEach.call on an array-like object).

Sign up to request clarification or add additional context in comments.

2 Comments

thanks! performance seems to be the main issue. But could you elaborate on 'you can't use the prototype to change methods for each instance on the fly'? not sure i understand
@Lior what I mean is that if you define the method Base.init, you can't override it with Base.prototype.init (including any "children" of it). It will use the one Base.init method you initially defined unless you explicitly call the other from the prototype chain
1

Basically it is quite simple, The Object.create is part of Ecmascript 5, which is quite new. Prototype has been around since the beginning of javascript and is supported by all the browsers.

So as long as you need support for Internet Explorer 7 or 8, you shouldn't be relying on Create. Also see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create

(The article also suggests a polyfill, which uses prototype ;-))

Comments

-2

You do not need the prototype (which IMHO is a con) for OO.

Consider this for inheritance:

function SubClass()
{
    var object = {};
    object.publicVar = 2;
    object.publicMethod = function SubClassPubMeth()
      {
        return this.publicVar + 2;
      };
    object.poly = function SubClassPoly()
      {
        return 'SubClassPoly';
      };
    return object;
}

function Class()
{
    var object = new SubClass();
    object.classPublicVar = 3;
    object.classPublicMethod =
        function ClassMethod()
        {
            return this.publicVar + this.classPublicVar;
        };
    object.poly = function ClassPoly()
      {
        return 'ClassPoly';
      };
    return object;
}

Seems to fit the bill for inheritance.

Also consider this for information hiding:

function Class() { var object = {}; object.x = 3; var privateVar = 3; function privateFunction(object) { return object.x + privateVar; }

object.publicFunction = function()
  {
    var priv = privateFunction(this);
    priv += privateVar;
    privateVar = privateVar + 3;
    return priv;
  };
return object;

}

Also seems to do the trick for information hiding (AKA encapsulation)

Need I say more.

2 Comments

If you are concerned about performances then you do need prototypes when you are subclassing , or whenever you are creating new instances of the same object.
The things that you do with Javascript does not require that much processing power. If you are concerned then you write the code using Java (for example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.