81 votes

Héritage JavaScript

J'essaie d'implémenter l'héritage en javascript. J'ai proposé le code minimal suivant pour le prendre en charge.

 function Base(){
    this.call = function(handler, args){
      handler.call(this, args);
    }
}

Base.extend = function(child, parent){
    parent.apply(child);
    child.base = new parent;
    child.base.child = child;
}
 

Experts, s'il vous plaît, faites-moi savoir si cela suffira ou si vous avez manqué un autre problème important. Sur la base de problèmes similaires rencontrés, veuillez suggérer d'autres changements.

Voici le script de test complet:

 function Base(){
    this.call = function(handler, args){
      handler.call(this, args);
    }
    this.superalert = function(){
        alert('tst');
    }
}

Base.extend = function(child, parent){
    parent.apply(child);
    child.base = new parent;
    child.base.child = child;
}

function Child(){
    Base.extend(this, Base);
    this.width = 20;
    this.height = 15;
    this.a = ['s',''];
    this.alert = function(){
        alert(this.a.length);
        alert(this.height);
    }
}

function Child1(){
    Base.extend(this, Child);
    this.depth = 'depth';
    this.height = 'h';
    this.alert = function(){
        alert(this.height); // display current object height
        alert(this.a.length); // display parents array length
        this.call(this.base.alert); 
          // explicit call to parent alert with current objects value
        this.call(this.base.superalert); 
          // explicit call to grandparent, parent does not have method 
        this.base.alert(); // call parent without overriding values
    }
}

var v = new Child1();
v.alert();
alert(v.height);
alert(v.depth);
 

141voto

Lorenzo Polidori Points 2903

Pour implémenter l'héritage javascript dans ECMAScript 5, vous pouvez définir le prototype d'un objet et utiliser Object.create pour hériter. Vous pouvez également ajouter / remplacer des propriétés autant que vous le souhaitez.

Exemple:

 /**
 * Transform base class
 */
function Transform() {
    this.type = "2d";
}

Transform.prototype.toString = function() {
    return "Transform";
}

/**
 * Translation class.
 */
function Translation(x, y) {
    // Parent constructor
    Transform.call(this);

    // Public properties
    this.x = x;
    this.y = y;
}

// Inheritance
Translation.prototype = Object.create(Transform.prototype);

// Override
Translation.prototype.toString = function() {
    return Transform.prototype.toString() + this.type + " Translation " + this.x + ":" + this.y;
}

/**
 * Rotation class.
 */
function Rotation(angle) {
    // Parent constructor
    Transform.call(this);

    // Public properties
    this.angle = angle;
}

// Inheritance
Rotation.prototype = Object.create(Transform.prototype);

// Override
Rotation.prototype.toString = function() {
    return Transform.prototype.toString() + this.type + " Rotation " + this.angle;
}

// Tests
translation = new Translation(10, 15);

console.log(translation instanceof Transform); // true
console.log(translation instanceof Translation); // true
console.log(translation instanceof Rotation); // false

console.log(translation.toString()) // Transform2d Translation 10:15
 

41voto

Marcosc Points 665

Je pense que la solution de Crockford est trop compliquée, tout comme celle de John. Il est beaucoup plus simple d'obtenir l'héritage javascript que les deux semblent décrire. Considérer:

 //Classes
function A() {
    B.call(this);
}

function B() {
    C.call(this);
    this.bbb = function() {
        console.log("i was inherited from b!");
    }
}

function C() {
    D.call(this);
}

function D() {
    E.call(this);
}

function E() {
    //instance property 
    this.id = Math.random()
}

//set up the inheritance chain (order matters) 
D.prototype = new E();
C.prototype = new D();
B.prototype = new C();
A.prototype = new B();

//Add custom functions to each
A.prototype.foo = function() {
    console.log("a");
};
B.prototype.bar = function() {
    console.log("b");
};
C.prototype.baz = function() {
    console.log("c");
};
D.prototype.wee = function() {
    console.log("d");
};
E.prototype.woo = function() {
    console.log("e");
};

//Some tests
a = new A();
a.foo();
a.bar();
a.baz();
a.wee();
a.woo();
console.log(a.id);
a.bbb();
console.log(a instanceof A);
console.log(a instanceof B);
console.log(a instanceof C);
console.log(a instanceof D);
console.log(a instanceof E);​
var b = new B();
console.log(b.id)
 

J'ai écrit une description complète de la solution ci-dessus sur mon blog .

12voto

bejonbee Points 2718

Si vous avez besoin d'héritage, de nombreuses bibliothèques l'offrent déjà. À tout le moins, lisez-les pour savoir où votre code est erroné. Mais pourquoi réinventer? Klass et selfish.js sont deux superbes bibliothèques d’héritage javascript qui me viennent à l’esprit (j’ai utilisé les deux, elles sont étonnantes).

12voto

Jan Turoň Points 6598

En jouant avec les objets JS, j'ai trouvé une solution plus minimaliste :-) Enjoy!

 function extend(b,a,t,p) { b.prototype = a; a.apply(t,p); }
 

Exemple

 function A() {
  this.info1 = function() {
    alert("A");
  }
}

function B(p1,p2) { extend(B,A,this);
  this.info2 = function() {
    alert("B"+p1+p2);
  }
}

function C(p) { extend(C,B,this,["1","2"]);
  this.info3 = function() {
    alert("C"+p);
  }
}


var c = new C("c");
c.info1(); // A
c.info2(); // B12
c.info3(); // Cc
 

8voto

Voici la plus simple et j'espère la meilleure façon de comprendre l'héritage dans JS. Le plus utile de cet exemple sera pour les programmeurs PHP.

 function Mother(){
    this.canSwim = function(){
        console.log('yes');
    }
}

function Son(){};
Son.prototype = new Mother;
Son.prototype.canRun = function(){
    console.log('yes');
}
 

Maintenant, le fils a une méthode remplacée et une nouvelle

 function Grandson(){}
Grandson.prototype = new Son;
Grandson.prototype.canPlayPiano = function(){
    console.log('yes');
};
Grandson.prototype.canSwim = function(){
    console.log('no');
}
 

Maintenant, le petit-fils a deux méthodes remplacées et une nouvelle

 var g = new Grandson;
g.canRun(); // => yes
g.canPlayPiano(); // => yes
g.canSwim(); // => no
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X