Maison  >  Article  >  interface Web  >  Comment utiliser les classes JS, les constructeurs et les fonctions d'usine

Comment utiliser les classes JS, les constructeurs et les fonctions d'usine

php中世界最好的语言
php中世界最好的语言original
2018-04-14 11:02:561636parcourir

Cette fois, je vais vous expliquer comment utiliser les classes JS, les constructeurs et les fonctions d'usine. Quelles sont les précautions lors de l'utilisation des classes, des constructeurs et des fonctions d'usine JS. ? Ce qui suit est un cas pratique, jetons-y un œil.

À l'ère ES6, nous avons plus de façons de créer des objets Nous pouvons choisir différentes méthodes pour les créer dans différents scénarios. Il existe actuellement trois manières principales de créer des objets : le mot-clé class, le constructeur et la fonction factory. Ce sont tous des moyens de créer des objets, mais ils sont différents. Lors du développement quotidien, il faut également choisir en fonction de ces différences.

Voyons d’abord à quoi ressemblent ces trois méthodes

// class 关键字,ES6新特性
class ClassCar {
 drive () {
  console.log('Vroom!');
 }
}
const car1 = new ClassCar();
console.log(car1.drive());
// 构造函数
function ConstructorCar () {}
ConstructorCar.prototype.drive = function () {
 console.log('Vroom!');
};
const car2 = new ConstructorCar();
console.log(car2.drive());
// 工厂函数
const proto = {
 drive () {
  console.log('Vroom!');
 }
};
function factoryCar () {
 return Object.create(proto);
}
const car3 = factoryCar();
console.log(car3.drive());

Ces méthodes sont basées sur la création de prototypes et prennent toutes en charge l'implémentation de variables privées dans la fonction constructeur. En d’autres termes, ces fonctions ont pour la plupart les mêmes caractéristiques et sont même équivalentes dans de nombreux scénarios.

En Javascript, chaque fonction peut renvoyer un nouvel objet. Lorsqu’il ne s’agit pas d’un constructeur ou d’une classe, on parle de fonction d’usine.

Les classes ES6 sont en fait du sucre syntaxique pour les constructeurs (du moins c'est ainsi qu'elles sont implémentées à ce stade), donc tout ce qui est discuté ensuite s'applique aux constructeurs ainsi qu'aux classes ES6 :

class Foo {}
console.log(typeof Foo); // function

Avantages des constructeurs et des classes ES6

  • La plupart des livres vous apprendront à utiliser des classes et des constructeurs

  • « ceci » pointe vers le nouvel objet.

  • Certaines personnes aiment la lisibilité du nouveau mot-clé

  • Il peut y avoir quelques petites différences dans les détails, mais s'il n'y a aucun problème pendant le processus de développement, ne vous inquiétez pas trop.

Inconvénients des constructeurs et des classes ES6

1. Vous avez besoin du nouveau mot-clé

Par ES6, les constructeurs et les classes doivent avoir le nouveau mot-clé.

function Foo() {
 if (!(this instanceof Foo)) { return new Foo(); }
}

Dans ES6, une tâche sera lancée si vous essayez d'appeler une fonction de classe sans le nouveau mot-clé. Si vous en voulez un sans le nouveau mot-clé, vous ne pouvez utiliser qu'une fonction d'usine pour l'envelopper.

2. Les détails du processus d'instanciation sont exposés à des API externes

Tous les appels sont étroitement liés à la mise en œuvre du constructeur. Si vous devez faire quelque chose pendant le processus de construction, ce sera une chose très gênante.

3. Le constructeur n'obéit pas à la règle Ouvert/Fermé

En raison de la gestion détaillée du nouveau mot-clé, le constructeur viole la règle Ouvert/Fermé : l'API doit être ouverte à l'expansion et éviter toute modification.

J'ai déjà demandé que les classes et les fonctions d'usine soient si similaires que la mise à niveau de la fonction de classe vers une fonction d'usine n'aurait aucun impact, mais en JavaScript, cela a un impact.

Si vous commencez à écrire un constructeur ou une classe, mais au fur et à mesure que vous continuez, vous constatez que vous avez besoin de la flexibilité de la fonction d'usine. À ce stade, vous ne pouvez pas simplement modifier la fonction et vous en aller.

Malheureusement, vous êtes un programmeur JavaScript, et transformer un constructeur en fonction factory est une opération majeure :

// 原来的实现:
// class Car {
//  drive () {
//   console.log('Vroom!');
//  }
// }
// const AutoMaker = { Car };
// 工厂函数改变的实现:
const AutoMaker = {
 Car (bundle) {
  return Object.create(this.bundle[bundle]);
 },
 bundle: {
  premium: {
   drive () {
    console.log('Vrooom!');
   },
   getOptions: function () {
    return ['leather', 'wood', 'pearl'];
   }
  }
 }
};
// 期望中的用法是:
const newCar = AutoMaker.Car('premium');
newCar.drive(); // 'Vrooom!'
// 但是因为他是一个库
// 许多地方依然这样用:
const oldCar = new AutoMaker.Car();
// 如此就会导致:
// TypeError: Cannot read property 'undefined' of
// undefined at new AutoMaker.Car

Dans l'exemple ci-dessus, nous avons commencé avec une classe et l'avons finalement transformée en une fonction d'usine capable de créer des objets basés sur un prototype spécifique. Une telle fonction peut être largement utilisée dans l'abstraction d'interface et la personnalisation de besoins spéciaux.

4. Utilisez des constructeurs pour donner une instance d'opportunité

La différence entre un constructeur et une fonction d'usine est l'instanceof opérateur De nombreuses personnes utilisent instanceof pour garantir l'exactitude de leur code. Mais pour être honnête, c’est un gros problème et il est recommandé d’éviter d’utiliser instanceof.

instanceof mentira.

// instanceof 是一个原型链检查
// 不是一个类型检查
// 这意味着这个检查是取决于执行上下文的,
// 当原型被动态的重新关联,
// 你就会得到这样令人费解的情况
function foo() {}
const bar = { a: 'a'};
foo.prototype = bar;
// bar是一个foo的实例吗,显示不是
console.log(bar instanceof foo); // false
// 上面我们看到了,他的确不是一个foo实例
// baz 显然也不是一个foo的实例,对吧?
const baz = Object.create(bar);
// ...不对.
console.log(baz instanceof foo); // true. oops.

instanceof ne vérifie pas comme les autres langages fortement typés, il vérifie simplement l'objet sur la chaîne prototype.

Dans certains contextes d'exécution, cela échouera, par exemple lorsque vous modifiez Constructor.prototype.

Un autre exemple est que vous commencez avec un constructeur ou une classe, puis que vous le développez en un autre objet, tout comme dans le cas où il a été réécrit en tant que fonction d'usine ci-dessus. À ce moment-là, instanceof aura également des problèmes.

Dans l’ensemble, instanceof est un autre changement majeur dans les appels de fonctions de constructeur et d’usine.

Avantages de l'utilisation des classes

  • Un mot-clé pratique et autonome

  • qui est le seul moyen faisant autorité pour implémenter une classe en JavaScript.

  • C'est une bonne expérience pour les autres développeurs qui ont de l'expérience dans le développement de langages de classe.

Inconvénients de l'utilisation des cours

Tous les inconvénients des constructeurs, plus :

Créer une classe problématique à l’aide du mot-clé extends est une grande tentation pour les utilisateurs.
L'héritage hiérarchique des classes peut causer de nombreux problèmes bien connus, notamment la classe de base fragile (la classe de base sera détruite à cause de l'héritage), la banane gorille problème (objets mélangés à des contextes complexes), duplication par nécessité (les classes doivent être modifiées de temps en temps lorsque l'héritage est diversifié), etc.

Bien que les deux autres méthodes puissent également vous poser ces problèmes, lorsque vous utilisez le mot-clé extend, l'environnement vous guidera dans cette voie. En d’autres termes, cela vous amène à écrire du code avec des relations inflexibles, plutôt qu’à écrire du code plus réutilisable.

Avantages de l'utilisation des fonctions d'usine

Les fonctions d'usine sont plus flexibles que les classes et les constructeurs et ne conduiront pas les gens sur la mauvaise voie. Cela ne vous coincera pas non plus dans une profonde chaîne d’héritage. Il existe de nombreuses façons de simuler l'héritage

1. Renvoyez n'importe quel objet avec n'importe quel prototype

Par exemple, vous pouvez créer différentes instances de la même implémentation, un lecteur multimédia peut créer des instances pour différents formats multimédias, en utilisant différentes API, ou une bibliothèque d'événements peut être destinée aux événements DOM ou ws.

Les fonctions Factory peuvent également instancier des objets via des contextes d'exécution, bénéficiant d'un pool d'objets et d'un modèle d'héritage plus flexible.

2. Ne vous inquiétez pas des refactorisations complexes

Vous n’aurez jamais besoin de convertir une fonction d’usine en constructeur, la refactorisation n’est donc pas nécessaire.

3. Pas de nouveau

Vous n'utilisez pas le mot-clé new pour créer un nouvel objet, vous pouvez maîtriser ce processus vous-même.

4. Standardisez ce comportement

c'est ce que vous connaissez et vous pouvez l'utiliser pour obtenir l'objet parent. Par exemple, dans player.create(), cela pointe vers le joueur, et d'autres peuvent également être liés via un appel et une application.

5. Aucun problème avec instanceof

6. Certaines personnes aiment la lisibilité et l'intuitivité de l'écriture directe sans nouveauté.

Inconvénients des fonctions d'usine

  • Il n'y a pas de traitement automatique des prototypes et les prototypes de fonctions d'usine n'affecteront pas la chaîne de prototypes.

  • cela ne pointe pas automatiquement vers le nouvel objet dans la fonction d'usine.

  • Il peut y avoir quelques petites différences dans les détails, mais s'il n'y a aucun problème pendant le processus de développement, ne vous inquiétez pas trop.

Conclusion

À mon avis, class est peut-être un mot-clé pratique, mais il ne peut cacher qu'il conduira les utilisateurs sans méfiance dans le gouffre de l'héritage. Un autre risque est la possibilité qu’à l’avenir vous souhaitiez utiliser les fonctions d’usine et que vous deviez procéder à des changements très importants.

Si vous travaillez dans une équipe relativement nombreuse, si vous souhaitez modifier une API publique, vous risquez d'interférer avec du code auquel vous n'avez pas accès, vous ne pouvez donc pas fermer les yeux sur l'impact des fonctions modifiées.

L'avantage du mode usine est qu'il est non seulement plus puissant et plus flexible, mais qu'il encourage également toute l'équipe à rendre l'API plus simple, plus sûre et plus légère.

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Utiliser nodejs pour appeler l'adresse de livraison dans WeChat

Que doit faire keep-alive dans vue2 Utilisez

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn