Javascript pseudo-classical inheritance and prototypal inheritance confusion example

I didn't really understand the difference between pseudo-classical and prototypal inheritance. Take a look at below code snippet.

Prototype: I can understand this code (Douglas Crockford). I have changed the class names and added an implementation for better understanding, since its code blocks are incomplete in the present.

var baseObject = {
    a : "old",
    firstMethod: function () {alert("First method");},
    secondMethod: function () {alert("Second method");}
};
var derivedObject = Object(baseObject);
alert(derivedObject.a);

derivedObject.thirdMethod = function () {alert("Third method");};
var derivedChildObject = Object(derivedObject);

derivedChildObject.firstMethod();
derivedChildObject.secondMethod();
derivedChildObject.thirdMethod();

      

Pseudo-classical:

Since I didn't get clarity from the same piece of code in my presentation as the methods are incomplete, I went to another link on the internet

http://javascript.info/tutorial/pseudo-classical-pattern

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

Animal.prototype = {
  canWalktrue,
  sitfunction() {
    this.canWalk = false
    alert(this.name + ' sits down.')
  }
}

var animal = new Animal('Pet'// (1)

alert(animal.canWalk) // true

animal.sit()             // (2)

alert(animal.canWalk) // false

      

Pseudo-class schema:

The default methods and properties are in the prototype. The methods in the prototype use this, which is the current object, because the meaning of that only depends on the calling context, so animal.sit () would set that animal.

Can you help me provide a correct example? You can take either animal use case or use baseObject for reference. Or come up with your own example

+3


source to share


2 answers


You are defining a property canwalk

at the object prototype level, so true

when you instantiate the object, you get an alert (animal.canWalk)

. The reason you got on the second alert false

is because you are calling the sit function where you are setting canwalk

to false.

This is why it is not good practice to strictly follow the prototypal inheritance pattern: typically, instances want to have their own copies of all properties. This is why the prototype pattern is rarely used by itself.

The most recommended is the use of Parasitic Combination Inheritance :

Combined inheritance is the most commonly used pattern for inheritance in JavaScript, although it's not without its inefficiency. The most inefficient part of the pattern is that the supertype constructor is always called twice: once to prototype the subtypes, and once inside the subtype constructor.

Essentially, the prototype of a subtype ends up with all the properties of an instance of the supertype object, only so that it is overwritten when the subtype's constructor is executed.

function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function(){
    alert(this.name);
};

function SubType(name, age){
    SuperType.call(this, name); //second call to SuperType()

    this.age = age;
}

SubType.prototype = new SuperType(); //first call to SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    alert(this.age);
};

      

To overcome this supertype, the constructor is always called twice, we can customize it using the following trick: instead of calling the supertype constructor to assign the subtype prototype, all we need is a copy of the supertype prototype:

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); //create object
    prototype.constructor = subType; //augment object
    subType.prototype = prototype; //assign object
}

      

Then we can replace:

SubType.prototype = new SuperType(); //first call to SuperType()
SubType.prototype.constructor = SubType;

      

from



inheritPrototype(SubType, SuperType);

      

Pseudo-classical inheritance:

Using this pattern, you define properties at the object level and methods at the object prototype level:

function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype = {
    constructor: SuperType,
    sayName : function() {
        alert(this.name);
    }
}

      

If you don't tell the constructor to SuperType

when you instantiate the object, the call will instanceof

still return true for Object

both SuperType

, but the constructor's property is now Object

of SuperType

.

var superType = new SuperType();
alert(superType instanceof Object); //true
alert(superType instanceof SuperType); //true
alert(superType.constructor == Person); //false
alert(superType.constructor == SuperType); //true

      

Example for inheritance:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
};

function SubType() {
    this.subproperty = false;
}

//inherit from SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function () {
    return this.subproperty;
};

//override existing method
SubType.prototype.getSuperValue = function () {
    return false;
};

      

Here are two very strong references to inheritance in Javascript:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/ http://www.allitebooks.com/professional-javascript-for-web-developers-3rd-edition/

+1


source


This is an example of prototypal inheritance

var Mammal = function() {
   this.isMammal = true;
};

var Cat = function() {
   this.meow = function() {
      alert('Cat says: MEOW!');
   };
};

Cat.prototype = new Mammal();
Cat.prototype.constructor = Cat;

var kitty = new Cat();
if(kitty.isMammal) {...}       // evaluates to true
kitty.meow();

      

Prototype inheritance is accomplished by reassigning the prototype to an instance of the base class. This will result in the prototype chain always ending with Object.prototype



If you are looking for a method or member, you start with an instance, then you work your way down the prototype chain until you find a method / member (or you don’t know).

Example for toString () and kitty from our example:

kitty.toString();

1. kitty instance doesn't have toString() method
2. Cat.prototype doesn't have toString() method
3. Mammal.prototype doesn't have toString() method
4. Object.prototype has toString() method, which will be called in the context of kitty

      

+2


source







All Articles