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:
jQuery
( jQuery.init
vs jQuery.fn.init
) 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:
jQuery
est une fonction d’usine permettant de créer des objects jQuery.Set
. 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.