Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript functional inheritance with prototypes

In Douglas Crockford's JavaScript: The Good Parts he recommends that we use functional inheritance. Here's an example:

var mammal = function(spec, my) {
    var that = {};
    my = my || {};

    // Protected
    my.clearThroat = function() { 
        return "Ahem";
    };

    that.getName = function() {
        return spec.name;
    };

    that.says = function() {
        return my.clearThroat() + ' ' + spec.saying || '';
    };

    return that;
};

var cat = function(spec, my) {
    var that = {};
    my = my || {};

    spec.saying = spec.saying || 'meow';
    that = mammal(spec, my);

    that.purr = function() { 
        return my.clearThroat() + " purr"; 
    };

    that.getName = function() { 
        return that.says() + ' ' + spec.name + ' ' + that.says();
    };

    return that;
};

var kitty = cat({name: "Fluffy"});

The main issue I have with this is that every time I make a mammal or cat the JavaScript interpreter has to re-compile all the functions in it. That is, you don't get to share the code between instances.

My question is: how do I make this code more efficient? For example, if I was making thousands of cat objects, what is the best way to modify this pattern to take advantage of the prototype object?

like image 247
cdmckay Avatar asked Mar 14 '10 02:03

cdmckay


People also ask

Is JavaScript prototype inheritance?

The Prototypal Inheritance is a feature in javascript used to add methods and properties in objects. It is a method by which an object can inherit the properties and methods of another object. Traditionally, in order to get and set the [[Prototype]] of an object, we use Object. getPrototypeOf and Object.

What is prototype in JS inheritance example?

In JavaScript, an object can inherit properties of another object. The object from where the properties are inherited is called the prototype. In short, objects can inherit properties from other objects — the prototypes.

Do functions have prototype JavaScript?

A Function object's prototype property is used when the function is used as a constructor with the new operator. It will become the new object's prototype. Note: Not all Function objects have the prototype property — see description.

Why is prototype inherited?

Prototypical inheritance allows us to reuse the properties or methods from one JavaScript object to another through a reference pointer function. All JavaScript objects inherit properties and methods from a prototype: Date objects inherit from Date.


2 Answers

Well, you just can't do it that way if you plan on making lots of mammal or cat. Instead do it the old fashioned way (prototype) and inherit by property. You can still do the constructors the way you have above but instead of that and my you use the implicit this and some variable representing the base class (in this example, this.mammal).

cat.prototype.purr = function() { return this.mammal.clearThroat() + "purr"; }

I'd use another name than my for base access and store it in this in the cat constructor. In this example I used mammal but this might not be the best if you want to have static access to the global mammal object. Another option is to name the variable base.

like image 162
Plynx Avatar answered Oct 01 '22 15:10

Plynx


Let me introduce you to Classical Inheritance that never uses prototype. This is a bad coding exercise but will teach you the real Classical Inheritance which always compared to prototypal inheritance:

Make a custructor:

function Person(name, age){
  this.name = name;
  this.age = age;
  this.sayHello = function(){return "Hello! this is " + this.name;}
}

Make another cunstructor that inherits from it:

function Student(name, age, grade){
  Person.apply(this, [name, age]);
  this.grade = grade
}

Very simple! Student calls(applies) Person on itself with name and age arguments takes care of grade arguments by itself.

Now lets make an instance of Student.

var pete = new Student('Pete', 7, 1);

Out pete object will now contain name, age, grade and sayHello properties. It owns all those properties. They are not uplinked to Person through prototype. If we change Person to this:

function Person(name, age){
  this.name = name;
  this.age = age;
  this.sayHello = function(){
    return "Hello! this is " + this.name + ". I am " this.age + " years old";
  }
}

pete will no recieve the update. If we call pete.sayHello, ti will return Hello! this is pete. It will not get the new update.

like image 45
Mohsen Avatar answered Oct 01 '22 16:10

Mohsen