Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending prototypes in Javascript - good way?

I want to validate that the approach I'm using is correct when it comes to extend a prototype - supposing "extend" is the right word.

This topic gets a lot of clones. I'm still trying to properly understand this topic...

The purpose is: - to write clean and good code. - to avoid using frameworks, if possible plain Javascript. - get advice on the clean frameworks that don't twist JS to obtain class-enabled behaviors.

Here is the Parent prototype of my sandbox:

function Parent(){

}

Parent.prototype = {

    "init":function(){

        this.name = "anon";
    },

    "initWithParameters":function(parameters){

        this.name = parameters.name ? parameters.name : "anon";
    },

    "talk": function(){

        console.log('Parent is: ' + this.name);
    }
}

Now the Child prototype - it adds a "position" property and redefines the behaviors:

function Child(){

    Parent.call(this);
}


Child.prototype = new Parent;
Child.prototype.constructor = Child;

Child.prototype.init = function(){

    Parent.prototype.call(this);

    this.setPosition(0, 0);
}

Child.prototype.initWithParameters = function(parameters){

    Parent.prototype.initWithParameters.call(this, parameters);

    if(!this.position){

        this.position = {x:0, y:0};
    }

    this.setPosition(parameters.pos.x, parameters.pos.y);
}

Child.prototype.setPosition = function(x, y){

    this.position.x = x;
    this.position.y = y;
}

Child.prototype.talk = function(){

    console.log('Child is: ' + this.name + ' and location is: ' + this.position.x + ', ' + this.position.y);
}

Is this a good practice? Is there no shorthand to avoid writing "Child.prototype." when overriding a property (using a litteral maybe, like the Parent prototype is written).

I know of J. Resig's Class/extend approach. But I'd rather use Javascript as the prototypical language it is, not make it work as a "class-like behaving class-less OO language".

Thanks for your help :-)

like image 228
Jem Avatar asked Feb 12 '15 21:02

Jem


People also ask

Should you use prototypes in JavaScript?

When a programmer needs to add new properties like variables and methods at a later point of time, and these properties need sharing across all the instances, then the prototype will be very handy. The prototype can add both variables and methods to an existing object dynamically.

Does prototype improve memory optimization?

'Prototype' helps remove code redundancy which helps boost your app's performance. If you are seeking to optimize resources or memory on your application, you should use prototype .

What is the use of Extend in JavaScript?

The extends keyword is used to create a child class of another class (parent). The child class inherits all the methods from another class. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.


2 Answers

In general your approach will work but a better approach will be to replace:

Child.prototype = new Parent;

with:

Child.prototype = Object.create(Parent.prototype);

This way you don't need to call new Parent, which is somewhat an anti-pattern. You could also define new properties directly as follows:

Child.prototype = Object.create(Parent.prototype, {
  setPosition: {
    value: function() {
      //... etc
    },
    writable: true,
    enumerable: true,
    configurable: true
  }
});

Hope this helps.

Object.create() at MDN

like image 53
skay- Avatar answered Oct 26 '22 00:10

skay-


Your approach it is a good pure JavaScript approach. The only get away from tipping "Child.prototype" every time is to put it in a reference variable.

Like:

  var children = Child.prototype;
  children.init = function(){ /*/someoverridecode*/}

But you are still doing the Child.prototype behind this. You can also define a function that does this for you, see bind of underscore, maybe it suits your needs.

Cheers

like image 41
Celeb Avatar answered Oct 26 '22 01:10

Celeb