Pourquoi le constructeur jQuery mappe-t-il à jQuery.fn.init?

Le constructeur jQuery correspondance ses fonctionnalités avec un autre constructeur, jQuery.fn.init :

 jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); }, 

Je me demande pourquoi

Cette question est très similaire, mais même le répondeur admet qu’il n’a pas vraiment répondu à la question de savoir pourquoi.

Cette question est toujours sans réponse

Est-ce juste pour des raisons d’organisation? Plutôt que de placer la fonction init dans la définition du constructeur jQuery, les auteurs ont peut-être voulu la conditionner.

Y a-t-il une raison d’avoir la méthode .init() sur le prototype? Je ne pense pas que quiconque utilise jamais $('.something')...init()...

Cette question montre qu’il n’est pas nécessaire d’avoir .init sur le prototype.

Et je viens de trouver cette question dans laquelle la réponse de Dan Herbert suggère que c’est simplement à des fins de structure / lisibilité.

En conclusion, puis-je confirmer que cette cartographie constructeur / prototype funny-business est un peu inutile? Il me semble que la fonctionnalité jQuery.fn.init pourrait aller:

  • N’importe où dans la fermeture
  • Sur l’object jQuery ( jQuery.init vs jQuery.fn.init )
  • Ou bien ce qui me semble le plus logique: directement dans la définition de la fonction / constructeur jQuery , en remplacement du new jQuery.fn.init et en évitant le jQuery.fn.init.prototype = jQuery.fn .

Le constructeur jQuery met en correspondance ses fonctionnalités avec un autre constructeur

Le fait est que jQuery n’est pas vraiment une fonction constructeur et ne devrait pas être considérée comme une fonction non plus. Par définition, la responsabilité du constructeur est d’initialiser les propriétés de l’instance, ce qui n’est pas vraiment le cas avec jQuery . De plus, appeler new jQuery() n’aurait aucun sens. jQuery est une fonction d’usine permettant de créer des instances de jQuery.fn.init , rien de plus .

Maintenant, vous vous demandez peut-être pourquoi ils n’ont tout simplement pas utilisé jQuery comme un véritable constructeur?

Eh bien, parce qu’ils ne voulaient pas d’un constructeur que nous appelons avec new tout le temps, ils voulaient une fonction factory. Cela me convient, mais je ne suis généralement pas d’accord avec cela, c’est que leur modèle est très cryptique et ne reflète pas vraiment l’intention .

À mon avis, il aurait été préférable de choisir de meilleurs noms:

 function jQuery(selector, context) { return new jQuery.Set(selector, context); } jQuery.Set = function (selector, context) { //constructor logic }; //allows syntaxic sugar jQuery.fn = jQuery.Set.prototype = { constructor: jQuery.Set, //methods }; 

J’ai à peu près seulement jQuery.fn.init en jQuery.Set et tout ça a plus de sens pour moi. En regardant le code ci-dessus, il est facile de voir que:

  1. jQuery est une fonction d’usine permettant de créer des objects jQuery.Set .
  2. jQuery.fn n’existe qu’en tant que sucre syntaxique, au lieu d’avoir à écrire jQuery.Set.prototype tout le temps pour modifier le prototype.

Maintenant, dans le source, nous voyons aussi qu’ils font ce qui suit, ce qui est un peu jQuery.prototype.init puisque jQuery n’est pas le constructeur réel, c’est jQuery.prototype.init et comme nous ne créons pas d’instances jQuery , définir jQuery.prototype semble inutile :

 jQuery.fn = jQuery.prototype = { constructor: jQuery 

Une des raisons derrière cela est certainement qu’ils veulent accueillir des personnes qui pourraient modifier jQuery.prototype au lieu de jQuery.fn .

Cependant, une autre raison valable est qu’ils souhaitaient peut-être somejQueryObj instanceof jQuery retournée soit vraie, alors qu’elle ne le ferait pas normalement. Si vous prenez le modèle ci-dessus (avec jQuery.Set), vous remarquerez que:

 jQuery() instanceof jQuery; //false jQuery() instanceof jQuery.Set; //true 

Cependant, si nous définissons le prototype de jQuery sur jQuery.Set.prototype , voyons ce qui se passe.

 jQuery.prototype = jQuery.Set.prototype; jQuery() instanceof jQuery; //true! 

Il n’est pas facile de comprendre tout ce qui a conduit à ces décisions de conception et peut-être me manque-t-il des points importants, mais il me semble que leur conception est trop compliquée.

Cela vous permet la chaîne du constructeur. Genre de…

Donc au lieu de

 $('.someClass').hide(); $('.someOtherClass').hide(); 

Tu peux faire

 $('.someClass').hide().init.call($.fn, '.someOtherClass').hide(); 

Cela fonctionne, mais c’est aussi une blague.