2009-11-03 5 views
2

En Javascript, chaque objet a un prototype. Tout prototype est un objet, donc tout prototype a un prototype.Javascript: mise en place d'une chaîne de prototypes

Cela me est:

var Person = function (name) { 
    this.name = name; 
} 

Person.prototype = { 
    walk: function() { 
     alert(this.name + ' is walking'); 
    } 
} 

var walter = new Person('Walter'); 

Je peux marcher:

walter.walk() // => "Walter is walking" 

Je me demande si les gens peuvent voler? Les programmeurs sont des dieux, je vais juste faire des gens capables de voler:

var WingedAnimal = function() { 
    this.hasWings = true; 
} 

WingedAnimal.prototype = { 
    fly: function() { 
     alert(this.name + ' is flying') 
    } 
} 

var Person = function (name) { 
    this.name = name; 
} 

Person.prototype = { 
    walk: function() { 
     alert(this.name + ' is walking'); 
    }, 
    prototype: new WingedAnimal() 
} 

var walter = new Person('Walter'); 

walter.walk() // => 'Walter is walking' 

walter.fly(); 

TypeError: walter.fly() n'est pas une fonction

OK puis:

Person.prototype = { 
    walk: function() { 
     alert(this.name + ' is walking'); 
    } 
} 

Person.prototype.prototype = new WingedAnimal(); 

var walter = new Person('Walter'); 

walter.walk() // => 'Walter is walking' 

walter.fly(); 

TypeError : walter.fly() n'est pas une fonction

Est-ce qu'il n'y a vraiment aucun moyen de faire cela? Je veux dire, avoir une chaîne de prototypes plutôt que de mélanger plusieurs objets dans un seul prototype?

Non pas que je n'aime pas mélanger les choses ensemble, mais quand même ...


Pour clarifier ma question:

Au moment où je l'ai déjà résolu ce problème avec une fonction que j'appelle habituellement mélanger et mettre dans un espace de noms généralement appelé CORE. La fonction copie les membres de tous les objets passés dans le premier objet. Mon code ressemble généralement à ceci:

var Constructor = function() { 
    // stuff 
} 

CORE.mix(Constructor.prototype, SomeInterface, AnotherInterface, { 
    //stuff that goes only into objects made with Constructor 
}); 

Tout dans UneInterface, AnotherInterface et l'objet se termine littéralement vers le haut dans Constructor.prototype, droit de priorité à gauche. Ce n'est pas, cependant, comment je pense que Javascript devrait fonctionner. Je devrais avoir, je pense, une chaîne de prototypes, pas seulement un prototype avec une tonne de choses mélangées dedans.

Lorsque j'appelle someObject.method, la méthode doit être recherchée dans someObject; si ce n'est pas le cas, il devrait être recherché dans someObject.prototype; puis dans someObject.prototype.prototype; et ainsi de suite jusqu'à ce qu'un prototype ait un prototype indéfini, alors il devrait échouer. C'est ainsi que je le comprends de this great explanation. Ai-je tort? Est un prototype pour chaque objet vraiment tout ce que nous pouvons utiliser?

Répondre

2
Person.prototype= { 
    walk: function() { 
      alert(this.name + ' is walking'); 
    }, 
    prototype: new WingedAnimal() 
} 

qui ne fonctionne pas: la vit propriété prototype sur la fonction constructeur, pas sur l'objet prototype:

Person.prototype= new WingedAnimal(); 
Person.prototype.walk= function() { 
    alert(this.name + ' is walking'); 
}; 

Cependant ceci est également erroné en ce qu'il essaie de fonder une classe sur une instance; cela fonctionne pour WingedAnimal parce que son constructeur ne fait pas grand-chose, mais c'est un mauvais modèle (promulgué par de nombreux mauvais tutoriels JS) qui va perturber toute tâche plus compliquée.

Voir this question pour un aperçu du prototypage en JavaScript.

+0

Cela a clarifié certaines choses, merci. Diriez-vous que mélanger tout dans le même prototype est une meilleure approche? –

+0

Eh bien, peu importe. Vous avez répondu, je vais trier le reste moi-même –

+0

Un prototype pour WingedAnimal et Person? J'espère que ce n'est qu'un exemple et que tout cas réel devrait être jugé sur ses propres mérites. Personnellement, je préfère les arbres prototypes relativement peu profonds à l'héritage profond de Java, mais je ne sais pas si je ferais d'une personne un WingedAnimal. (!) – bobince

3

Je pense que vous ne comprenez pas la propriété du prototype. Bien que tous les objets aient une référence interne à leur prototype, il n'y a aucun moyen de l'obtenir ou de le définir directement dans chaque navigateur. La propriété prototype n'est utile que lorsqu'elle est affectée à des fonctions constructeur.

Person.prototype = new WingedAnimal(); 

Person.prototype.walk = function() { 
    alert(this.name + ' is walking'); 
}; 

var walter = new Person('Walter'); 

walter.walk() // => 'Walter is walking' 

walter.fly();