Java-esque OOP en JavaScript et un échec jQuery

Je travaille sur un projet et j'essaie vraiment d'écrire un code JavaScript orienté objet. Je viens juste de lire le JavaScript de Douglas Crockford: The Good Parts et je commence à me rendre compte que l'écriture d'OOP Java-JavaScript est une tâche difficile.

Jusqu'à présent, j'ai écrit quelque chose comme le suivant …

// index.html $(document).ready(function() { $().SetUpElements(); }); // this is in a different js file $.fn.SetUpElements = function() { // do stuff here $().UpdateElement(); }; // this is in yet another different js file $.fn.UpdateElement = function() { // do stuff here var element = new Element(id, name); // continue doing work }; function Element(id, name) { var id = id; var name = name; // other stuff }; 

… l'idée étant que je veux que les objets / fonctions soient refactués et découplés autant que possible; Je souhaite réutiliser autant de code que possible. J'ai répandu beaucoup de mon code sur différents fichiers .js dans le but de regrouper un code pertinent spécifique, tout comme si vous écririez différentes classes en Java.

Comme j'ai appris plus sur jQuery, j'ai réalisé que la notation $.fn.foo = function() { ... }; Est en train d'ajouter cette fonction foo au prototype de tous les objets jQuery. Est-ce quelque chose que je devrais faire? Est-ce que je maltraite jQuery en quelque sorte?

J'apprécierais des suggestions sur la façon d'améliorer mon approche de OOP en JavaScript et j'aimerais voir des références à des sources / tutoriels / articles / etc … qui traitent de ce sujet. N'hésitez pas à fournir des commentaires même si une réponse a été sélectionnée. Je cherche tes conseils … C'est pourquoi j'ai posté 🙂

** Remarque: Je ne développe pas un plugin jQuery. Je développe une application Web et j'utilise fortement jQuery.

Je dirais que la première façon de créer des méthodes est une mauvaise utilisation de jQuery. La syntaxe jQuery.fn.foo est généralement réservée aux fonctions qui agissent sur un élément DOM mais que vous les utilisez comme fonctions statiques, en utilisant un objet jQuery vide.

Si vous souhaitez créer des fonctions statiques sous l'espace de nommage jQuery, vous pouvez:

 jQuery.foo = function(){}; 

Puis appelez-le via:

 jQuery.foo(); 

au lieu de:

 jQuery.fn.foo = function(){}; 

Qui vous permet de faire:

 jQuery('#someElementId').foo(); 

En termes d'OOP. Il existe de nombreuses approches différentes (modèle de module, prototype, usine …). La façon dont je l'approche généralement, est de créer une classe comme une fonction statique, puis de l'invoquer avec le mot-clé new

 (function($){ var undefined; $.ClassName = function(options){ var self = this; var cfg = $.extend(true, {}, this.defaults, options); // ******************** // start:private // ******************** function _init(){ }; // ******************** // start:public // ******************** this.methodName = function(){ }; _init(); }; $.ClassName.prototype.defaults = {}; })(jQuery); 

En termes de réutilisation des fonctionnalités, il existe un seuil après lequel le découplage est plus préjudiciable que n'importe quoi. Assurez-vous de garder le bon équilibre entre la modularité et l'organisation.

Si ce n'est pas un plugin jquery, j'écris quelque chose comme ceci:

  var app = { init: function(){ app.SetUpElements(); }, SetUpElements: function() { return 'something'; }, etc: function() { } }; $(document).ready(app.init); 

En référence à OO en Javascript, vous devriez regarder les cours de Javascript avancé de Douglas Crockford

Si vous développez un plug-in, il est généralement préférable d'éviter de contaminer les espaces de noms et prototypes jQuery et Global autant que possible.

Jetez un oeil à cette documentation sur le site Web de jQuery , qui donne une excellente explication de la façon de fournir l'accès à une variété de fonctionnalités réutilisables, tout en revendiquant un seul nom sur l'objet jQuery.

Une autre méthode que j'ai utilisée est de fournir une fonction d'init unique pour votre plug-in sur l'espace de noms de jQuery, puis de créer un nom supplémentaire de plug-in spécifique dans l'espace de noms global, qui offre un accès plus direct aux fonctions / membres, etc. Le plug-in Galleria est un excellent exemple de la façon de bien le faire. Examinez leur documentation et la façon dont ils configurent la structure du plug-in.

MODIFIER

Après avoir vu que vous ne faites pas de plug-in: Beaucoup de choses que j'ai dit s'appliquent toujours au développement général de jQuery (et vraiment au développement en général).

Dans votre cas particulier, puisque vous n'utilisez pas les sélecteurs jQuery pour effectuer vos appels de fonction, ces fonctions pourraient probablement être aussi facilement attachées à un prototype de votre propre création, qui pourrait être placé dans l'espace de noms global.

En ce qui concerne l'espace de noms, regardez la réponse acceptée sur cette question pour un exemple de la façon de procéder correctement: Comment déclarer un espace de noms en JavaScript?

Et voici une excellente ressource pour OO en JavaScript. J'ai utilisé cet article lorsque j'essayais de mettre en avant le concept: http://mckoss.com/jscript/object.htm

Il semble que vous écrivez tout votre code en tant que plug-ins jQuery? Je ne ferais pas ça. Créez votre propre espace de noms.

Quel est l'objectif de mettre tout dans différents fichiers? Sauf si ce sont des scripts qui seront utilisés pour des pages spécifiques, cela rend plus difficile la gestion des choses. Tout cela ressemble à des fonctions générales de bibliothèque. Sauf si vous pensez que vous voudrez charger certains sur une seule page, mais pas tous, puis les mettre dans un seul fichier.

La programmation orientée objet ne signifie pas fragmenter les choses à travers les fichiers. C'est juste une organisation, vous devez diviser les choses en différents fichiers lorsque vous n'avez pas besoin de tous les contenus sur une page.

Comme la plupart l'ont déjà mentionné, sauf si vous créez explicitement un plugin public, n'utilisez pas les fonctions personnalisées de jQuery. Créez plutôt votre propre espace de noms en utilisant une notation simple d'objet, ou quelque chose de plus robuste, comme le modèle de module . Si vous voulez devenir fou, vous pouvez utiliser une API au dessus d'une API pour obtenir un modèle OO plus classique en utilisant Dean Edward's Base . L'objectif final est d'extraire vos exigences fonctionnelles et de conception à partir de l'API jQuery. De cette façon, si vous aviez besoin de transporter quelque chose sur Mootools ou Prototype, il serait beaucoup plus simple à accomplir.