Dans la plupart des langages de programmation, il existe des classes et des objets, et une classe peut hériter d'autres classes.
Dans JavaScript, l'héritage est basé sur un prototype, ce qui signifie qu'il n'y a pas de classes dans JavaScript, et à la place, un objet hérite d'un autre objet. :)
1. Héritage, le proto
En JavaScript, lorsqu'un lapin d'objet hérite d'un autre animal d'objet, cela signifie qu'il y aura une propriété spéciale dans l'objet de lapin: lapin .__ Proto__ = animal;
Lorsque vous accédez à un objet de lapin, si l'interprète ne peut pas trouver la propriété dans le lapin, il suivra la chaîne __proto__ pour rechercher dans l'objet animal
L'attribut __proto__ dans les châtaignes n'est accessible que dans Chrome et Firefox. Veuillez consulter un châtaignier:
var animal = {manger: true} var lapin = {sauts: true} lapin .__ proto__ = animal // hériter (lapin.eats) // vraiL'attribut Eats est accessible à partir d'un objet animal.
Si l'attribut a été trouvé dans l'objet Rabbit, l'attribut Proto ne sera pas vérifié.
Ayons une autre châtaignier. Lorsqu'il y a aussi un attribut Eats dans la sous-classe, la classe parent ne sera pas accessible.
var animal = {manger: true} var feduprabbit = {manger: false} feduprabbit .__ proto__ = alerte animale (feduprabbit.eats) // fauxVous pouvez également ajouter une fonction en animal, et il peut également être accessible en lapin.
var animal = {eat: function () {alert ("je suis plein") this.full = true}} var lapin = {saut: function () {/ * quelque chose * /}} lapin .__ proto__ = animal(1) lapin.eat ():
La fonction lapin.eat () est exécutée dans les deux étapes suivantes:
Tout d'abord, l'interprète recherche le lapin.eat. Il n'y a pas de fonction d'EAT dans le lapin, il regarde donc le lapin .__ Proto__ et l'a trouvé en animal.
La fonction fonctionne avec ce = lapin. Cette valeur n'a rien à voir avec l'attribut __proto__.
Donc, this.full = vrai chez le lapin:
Voyons quelles nouvelles découvertes nous avons faites ici. Un objet appelle la fonction parent, mais cela pointe toujours vers l'objet lui-même, qui est l'héritage.
L'objet référencé par __proto__ est appelé prototype, et Animal est le prototype de lapin (Note du traducteur: Il s'agit de l'attribut __proto__ du lapin se réfère à l'attribut prototype de l'animal)
(2) Rechercher lorsque vous lisez, pas lorsque vous écrivez
Lors de la lecture d'un objet, comme celui-ci.prop, l'interprète recherche des propriétés dans son prototype.
Lorsque vous définissez une valeur d'attribut, comme ce.prop = valeur, il n'y a aucune raison de rechercher, et cet attribut (prop) sera ajouté directement à cet objet (c'est celui-ci). Supprimer obj.prop est similaire, il supprime uniquement les propriétés de l'objet lui-même et les propriétés du prototype restent intactes.
(3) À propos de Proto
Si vous lisez le guide, nous appelons ici __proto__, qui est représenté dans le guide comme [[Prototype]]. Les deux supports sont importants car il existe une autre propriété appelée prototype.
2. Object.Create, object.getprototypeof
__proto__ est une propriété non standard fournie par Chrome / Firefox et reste invisible dans d'autres navigateurs.
Tous les navigateurs modernes à l'exception de l'opéra (c'est-à-dire> 9) prennent en charge deux fonctions standard pour gérer les problèmes de prototype:
Object.ceate (prop [, accessoires])
Créez un objet vide avec le proto donné:
var animal = {manger: true} lapin = objet.create (animal) alert (lapin.eats) // trueLe code ci-dessus crée un objet de lapin vide et le prototype est défini sur Animal
Une fois l'objet de lapin créé, nous pouvons y ajouter des propriétés:
var animal = {manger: true} lapin = objet.create (animal) lapin.jumps = trueLe deuxième paramètre de la fonction Object.Creat est facultatif, ce qui permet de définir les propriétés comme de nouveaux objets. Ceci est omis en raison de l'héritage de notre relation.
(1) objet.getprototypeof (obj)
Renvoie la valeur d'Obj .__ Proto__. Cette fonction est standard et peut être utilisée dans les navigateurs qui ne peuvent pas accéder directement à l'attribut __proto__.
var animal = {manger: true} lapin = object.create (animal) alert (object.getprototypeof (lapin) === animal) // trueLes navigateurs modernes permettent la lecture des valeurs d'attribut __proto__, mais elles ne peuvent pas être définies.
3. Le prototype
Il existe de bonnes façons de croix de définir l'attribut __proto__, qui utilisera les fonctions du constructeur. souviens-toi! Toute fonction crée un objet via le nouveau mot-clé.
Une châtaignier:
fonction lapin (nom) {this.name = name} var lapin = nouveau lapin ('John') alert (lapin.name) // JohnLa nouvelle opération définit les propriétés du prototype à la propriété __proto__ de l'objet Rabbit.
Jetons un coup d'œil à son principe, par exemple, un nouvel objet de lapin, qui hérite de l'animal.
var animal = {Eats: true} function lapin (nom) {this.name = name} lapin.prototype = animalvar lapin = nouveau lapin ('John') alert (lapin.eats) // true, parce que le lapin .__ proto__ == animalLapin.prototype = animal littéral signifie: set __proto__ = animal pour tous les objets créés par le nouveau lapin
4. Objet croisé.
Object.Create (PROP) La fonction est puissante car elle permet l'héritage direct d'un objet donné. Il peut être simulé par le code suivant:
Fonction hériter (proto) {fonction f () {} f.prototype = proto return new f}L'héritage (animal) est exactement équivalent à objet.Create (animal), renvoie un objet vide et un objet .__ Proto__ = animal.
Une châtaignier:
var animal = {Eats: true} var lapin = hériter (animal) alert (lapin.eats) // trueAlert (lapin.hasownproperty ('manger')) // false, à partir du prototypeJetons un coup d'œil à son principe:
Fonction hériter (proto) {fonction f () {} // (1) f.prototype = proto // (2) renvoie nouveau f () // (3)}(1) Une nouvelle fonction a été créée, et la fonction n'a établi aucun attribution à cela, donc `nouveau F` créera un objet vide.
(2) «F.prototype» est défini sur Proto
(3) «New» F crée un objet vide, `__proto__ = f.prototype» de l'objet
(4) Bingo! Nous obtenons un objet vide héritant de «proto»
Cette fonction est largement utilisée dans diverses bibliothèques et frameworks.
Votre fonction accepte un objet avec des options
/ * Options contiennent des paramètres de menu: largeur, hauteur etc. 300 // Définir la valeur par défaut // ...}
. . . Mais la modification de la valeur du paramètre peut produire de mauvais résultats, car les options peuvent être utilisées dans le code externe. Une solution consiste à cloner l'objet Options, à copier tous les attributs dans un nouvel objet et à le modifier dans le nouvel objet.
Comment résoudre ce problème avec l'héritage? Les options PS peuvent ajouter des paramètres, mais ne peuvent pas être supprimés.
Solution
Vous pouvez hériter d'options et modifier ou ajouter de nouvelles propriétés dans sa sous-classe.
Fonction INHERIT (Proto) {fonction f () {} f.prototype = proto return new f} menu function menu (options) {var opts = iNherit (options) opts.width = opts.width || 300 // ...}Toutes les opérations ne sont valables que dans les sous-objets. Lorsque la méthode du menu se termine, le code externe peut toujours utiliser des objets d'options non modifiés. Supprimer l'opération est très importante ici. Si la largeur est une propriété dans un prototype, Delete Opts.Width n'aura aucun effet
5. Hasownproperty
Tous les objets ont une fonction deproperty, qui peut être utilisée pour détecter si une propriété est elle-même ou un prototype.
Une châtaignier:
fonction lapin (name) {this.name = name} lapin.prototype = {manats: true} var lapin = new lapin ('John') alert (lapin.hasownproperty ('mange')) // false, dans prototypelert (lapin.hasownproperty ('name')) // true, dans objet6. boucle avec / sans propriétés héritées
pour..in Loop produit toutes les propriétés d'un objet, y compris le sien et le prototype.
fonction lapin (nom) {this.name = name} lapin.prototype = {mange: true} var lapin = new lapin ('John') pour (var p dans lapin) {alert (p + "=" + lapin [p]) // produit à la fois "nom" et "mange"}Utilisez HasownProperty pour filtrer les propriétés de l'objet:
fonction lapin (name) {this.name = name} lapin.prototype = {manats: true} var lapin = new lapbbit ('John') pour (var p dans lapin) {if (! rabbit.hasownproperty (p)) continu // sort unique7. Résumé
JavaScript met en œuvre l'héritage via un proto d'attribut spécial
Lorsque vous accédez aux propriétés d'un objet, si l'interprète ne peut pas le trouver dans l'objet, il continuera à rechercher les propriétés de fonction, cela pointe vers l'objet, pas son prototype.
Attribuer obj.prop = valeur, supprimer obj.prop
Gérer Proto:
Chrome et Firefox peuvent accéder directement à l'attribut __proto__ de l'objet. La plupart des navigateurs modernes prennent en charge l'accès en lecture seule à l'aide d'object.getPrototypeOf (OBJ).
Object.Create (Proto) peut générer des objets enfants vides avec le proto donné, ou atteindre la même fonction via le code suivant:
Fonction hériter (proto) {fonction f () {} f.prototype = proto return new f ()}Autres méthodes:
Pour..in Loop produit toutes les propriétés d'un objet (y compris le sien et le prototype) et la chaîne prototype de l'objet.
Si une propriété appartient à l'objet obj, alors obj.hasownproperty (prop) renvoie true, sinon faux.