103 votes

Comment hériter d’une classe en javascript ?

En PHP/Java, on peut faire :

Et tout public/protéger automatiquement les méthodes, propriétés, champs, etc. de la classe Super devenue une partie de la classe Sub qui peut être remplacée si nécessaire.

Quel est l’équivalent pour ça en Javascript ?

192voto

CMS Points 315406

En JavaScript, vous n'avez pas de classes , mais vous pouvez obtenir l'héritage et le comportement de la réutilisation de plusieurs façons:

Pseudo-classique héritage (par le biais de prototypage):

function Super () {
  this.member1 = 'superMember1';
}
Super.prototype.member2 = 'superMember2';

function Sub() {
  this.member3 = 'subMember3';
  //...
}
Sub.prototype = new Super();

Doit être utilisé avec l' new opérateur:

var subInstance = new Sub();

Fonction de l'application ou de "constructeur de chaîne":

function Super () {
  this.member1 = 'superMember1';
  this.member2 = 'superMember2';
}


function Sub() {
  Super.apply(this, arguments);
  this.member3 = 'subMember3';
}

Cette approche devrait également être utilisés avec l' new opérateur:

var subInstance = new Sub();

La différence avec le premier exemple est que nous, en apply le Super constructeur à l' this objet à l'intérieur d' Sub, il ajoute les propriétés affectées à l' this sur Super, directement sur la nouvelle instance, par exemple, subInstance contient les propriétés member1 et member2 directement (subInstance.hasOwnProperty('member1') == true;).

Dans le premier exemple, ces propriétés sont accessibles par le biais de la chaîne de prototype, ils existent à l'interne en [[Prototype]] objet.

Parasite de l'héritage ou de la Puissance des Constructeurs:

function createSuper() {
  var obj = {
    member1: 'superMember1',
    member2: 'superMember2'
  };

  return obj;
}

function createSub() {
  var obj = createSuper();
  obj.member3 = 'subMember3';
  return obj;
}

Cette approche est basée pour l'essentiel sur l'objet "augmenter", vous n'avez pas besoin d'utiliser l' new de l'opérateur, et comme vous pouvez le voir, l' this mot-clé n'est pas impliqué.

var subInstance = createSub();

ECMAScript 5 Ed. Object.create méthode:

// Check if native implementation available
if (typeof Object.create !== 'function') {
  Object.create = function (o) {
    function F() {}  // empty constructor
    F.prototype = o; // set base object as prototype
    return new F();  // return empty object with right [[Prototype]]
  };
}

var superInstance = {
  member1: 'superMember1',
  member2: 'superMember2'
};

var subInstance = Object.create(superInstance);
subInstance.member3 = 'subMember3';

La méthode ci-dessus est une prototypes héritage technique proposée par Crockford.

Les instances d'objet hériter d'autres instances de l'objet, c'est tout.

Cette technique peut être mieux qu'un simple objet "d'augmentation", parce que les propriétés héritées ne sont pas copiées toutes les nouvelles instances de l'objet, depuis la base de l'objet est définie comme l' [[Prototype]] de l' étendue de l'objet, dans l'exemple ci - subInstance contient physiquement seulement l' member3 de la propriété.

81voto

Bjorn Tipling Points 16243
function Base ( ) {
  this.color = "blue";
}

function Sub ( ) {

}
Sub.prototype = new Base( );
Sub.prototype.showColor = function ( ) {
 console.log( this.color );
}

var instance = new Sub ( );
instance.showColor( ); //"blue"

7voto

naivists Points 15639

Eh bien, en JavaScript, il n'est pas question de "l'héritage de classe", il y a juste "l'héritage de prototype". Afin de ne pas faire une catégorie "camion" et puis marquez-le comme une sous-classe de "automobile". Au lieu de cela, vous rendre un objet "Jack" et dire qu'il utilise des "John" comme un prototype. Si John sait, combien de "4+4", puis Jack le sait, trop.

Je vous suggère de lire Douglas Crockford de l'article sur les prototypes de l'héritage ici: http://javascript.crockford.com/prototypal.html Il montre également comment vous pouvez le faire en JavaScript ont un "look-alike" héritage comme dans d'autres langages à objets et explique ensuite que cela signifie réellement la rupture de javaScript dans un sens, il n'était pas destiné à être utilisé.

6voto

Luke Points 1780

Je trouve cette citation d'être la plus éclairante:

En essence, un JavaScript "classe" n'est qu'une Fonction de l'objet qui sert en tant que constructeur, en plus d'un attaché objet prototype. (Source: Le Gourou De Katz)

J'aime utiliser des constructeurs plutôt que des objets, donc je suis partie à la "pseudo-classique de l'héritage de la" méthode décrite ici par la CMS. Voici un exemple de l'héritage multiple avec un prototype de la chaîne:

// Lifeform "Class" (Constructor function, No prototype)
function Lifeform () {
    this.isLifeform = true;
}

// Animal "Class" (Constructor function + prototype for inheritance)
function Animal () {
    this.isAnimal = true;
}
Animal.prototype = new Lifeform();

// Mammal "Class" (Constructor function + prototype for inheritance)
function Mammal () {
    this.isMammal = true;
}
Mammal.prototype = new Animal();

// Cat "Class" (Constructor function + prototype for inheritance)
function Cat (species) {
    this.isCat = true;
    this.species = species
}
Cat.prototype = new Mammal();

// Make an instance object of the Cat "Class"
var tiger = new Cat("tiger");

console.log(tiger);
// The console outputs a Cat object with all the properties from all "classes"

console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
// Outputs: true true true true

// You can see that all of these "is" properties are available in this object
// We can check to see which properties are really part of the instance object
console.log( "tiger hasOwnProperty: "
    ,tiger.hasOwnProperty("isLifeform") // false
    ,tiger.hasOwnProperty("isAnimal")   // false
    ,tiger.hasOwnProperty("isMammal")   // false
    ,tiger.hasOwnProperty("isCat")      // true
);

// New properties can be added to the prototypes of any
// of the "classes" above and they will be usable by the instance
Lifeform.prototype.A    = 1;
Animal.prototype.B      = 2;
Mammal.prototype.C      = 3;
Cat.prototype.D         = 4;

console.log(tiger.A, tiger.B, tiger.C, tiger.D);
// Console outputs: 1 2 3 4

// Look at the instance object again
console.log(tiger);
// You'll see it now has the "D" property
// The others are accessible but not visible (console issue?)
// In the Chrome console you should be able to drill down the __proto__ chain
// You can also look down the proto chain with Object.getPrototypeOf
// (Equivalent to tiger.__proto__)
console.log( Object.getPrototypeOf(tiger) );  // Mammal 
console.log( Object.getPrototypeOf(Object.getPrototypeOf(tiger)) ); // Animal
// Etc. to get to Lifeform

Voici une autre bonne ressource de MDN, et ici est un jsfiddle de sorte que vous pouvez l'essayer.

3voto

darren Points 8541

vous ne pouvez pas (au sens classique). Javascript est un langage prototypique. Vous remarquerez que vous ne déclarez jamais une "classe" en Javascript; vous définissez simplement l'état et les méthodes d'un objet. Pour produire un héritage, vous prenez un objet et le prototypez. Le prototype est étendu avec de nouvelles fonctionnalités.

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