Mon objectif final est de pouvoir faire quelque chose comme ceci: assez idiot, même après avoir lu comment les variables sont déclarées, en regardant le code JQuery, ... je suis toujours Je ne peux pas avoir la tête autour de ça. P> C'est ce que j'ai essayé jusqu'à présent, mais il échoue: p>
8 Réponses :
Lorsque vous faites Vous créez un objet qui a deux attributs déplacer code> et impression code>. Votre objet test code> n'est plus une fonction en raison de la relève nouvelle code>. Alors appeler test () code> est faux. P> p>
Appelant Test (). Déplacer () code> est faux si vous essayez d'instancier un objet code> objet code>, mais enchaînant les appels de fonction (la clé de la mise en œuvre de JQuery) est très possible.
Vous pouvez transmettre la valeur 'Azerty' comme paramètre sur MyClass Constructor et modifier le test ('azerty'). Déplacez () sur Test.Move ()
<script type="text/javascript">
var MyClass = function(context) {
this.print = function(){
console.log("Printing");
}
this.move = function(){
console.log(context);
return context;
}
};
var test = new MyClass('azerty');
test.print(); // Works
console.log('Moving: ' + test.move() ); // Type property error
</script>
Chaque fois que vous appelez $ code> dans jQuery, il renvoie un nouveau jQuery.init code> objet. L'objet jquery.init code> a des fonctions qui sont ensuite appelées. test.a.prototype.move = function()
{
//move function defined for the a object
return this;
};
jQuery () code> est à la fois un module avec des méthodes globales et un constructeur. Il appelle automatiquement un constructeur s'il doit. Si nous ne sommes pas appelés avec un mot-clé code> neuf code>, alors ceci code> n'aura pas été construit avec myClass code>. Nous pouvons détecter cela et appeler la fonction en mode constructeur à la place. Une fois que nous faisons cela, alors ceci code> sera une instance de myClass code> et nous pouvons commencer à ajouter des trucs. var MyClass = function(context) {
// if the function is called without being called as a constructor,
// then call as a constructor for us.
if (this.__proto__.constructor !== MyClass) {
return new MyClass(context);
}
// Save the context
this.context = context;
// methods...
this.print = function() {
return "Printing";
}
this.move = function() {
return this.context;
}
};
$('#output').append('<li>print(): '+ MyClass().print() +'</li>');
$('#output').append('<li>move():'+ MyClass('azerty').move() +'</li>');
$('#output').append('<li>context: '+ MyClass('azerty').context +'</li>');
Maintenant je comprends. Il doit encore être instancié, mais cela peut être fait de l'intérieur. Jolie cool, merci!
Heureux d'aider! De plus, je viens de mettre à jour ma réponse avec une meilleure façon de détecter s'il s'agissait d'appelé constructeur ou non en vérifiant en réalité le constructeur du prototype de Ceci code>. Devrait être beaucoup plus robuste.
Même si cela fonctionne comme je le souhaite, je viens de comprendre que (parce que c'est instancié pour chaque appel de myClass (), il est assez lent pour mon but. Vous vivez et apprenez: p
Comme j'écris ceci, la réponse de Squeegy a le plus grand nombre de votes: 7. Pourtant, il est faux parce que Ceci (un peu simplifié) est la façon dont JQuery le fait effectivement ( Essayez même sur IE 6 ), et il comprend également des exemples de méthodes statiques et de chaînage de méthode. Pour tous les détails de la façon dont JQuery le fait, bien sûr, vous devrez vérifier le JQuery Source Code vous-même. p> Notez que si vous avez besoin de données" privées ", vous devrez mettre des méthodes d'instance à l'intérieur __ proto __ code> est non standard et n'est pas pris en charge par Internet Explorer (même la version 8). Cependant, se débarrasser de __ proto __ code> ne fonctionne pas non plus dans IE 6. MyClass. init code> (avec une variable déclarée juste à l'intérieur de cette fonction) comme this.print = fonction () {...}; code> au lieu d'utiliser myclass.init.pototype code >. p> p>
Tout d'abord, jQuery utilise un motif qui est plus proche d'un monad em>, un usine em> ou une combinaison des deux. Néanmoins, voici ce que j'utilise dans mes projets car le motif, lui-même, est tellement associé à la classe que vous souhaitez utiliser: p> essentiellement, vous peut l'utiliser comme une fonction, un objet et d'utiliser le mot-clé - ou - p> Ce serait, par exemple , accumulez une nodéliste de plusieurs éléments (1ère expression), ou percez jusqu'à un élément spécifique em> (2e). p> espère que cela aide p> h2> nouveau code> pour construire un autre objet / fonction unique. Vous pouvez l'utiliser pour appliquer une méthode arbitre em> (par défaut, comme la méthode Rechercher code> ci-dessus) ou utilisez différentes méthodes sur la base de quels paramètres sont entrés. Par exemple, vous pouvez faire quelque chose comme: p>
J'ai récemment travaillé sur un exercice qui a demandé de recréer une bibliothèque de jQuery comme uniquement en utilisant ES6.
à partir des points ci-dessus, j'ai pu créer la logique d'instanciation permettant d'appeler des méthodes sur les noms de classe Selectors E.g. p>
Lorsque l'instance de $ T est appelée avec un sélecteur, une nouvelle instance de TLIB $ est créée sur le sélecteur particulier qui contiendra toutes les méthodes pouvant être utilisées sur le sélecteur avec les éléments en contexte . P>
J'ai ajouté quelques méthodes qui sont chaînées dans l'exemple ci-dessous qui vous permet d'ajouter une classe CSS à un élément et de supprimer la même classe dans un appel, par exemple: P>
const $T = (selector) => {
// returns the HTML elements that match the selector
const elements = document.querySelectorAll(selector);
return new $TLib(elements, selector);
};
class $TLib {
constructor (elements) {
this._elements = elements;
}
addClass (className) {
this._elements.forEach((element) => element.classList.add(className));
return this;
}
removeClass (className) {
this._elements.forEach((element) => element.classList.remove(className));
return this;
}
toggleClass (className) {
this._elements.forEach((element) => {
const classList = element.classList;
(classList.contains(className)) ? classList.remove(className) : classList.add(className);
});
return this;
}
}
Les solutions fournies jusqu'à présent ne semblent pas refléter la structure exacte de JQuery (ou JQuery changé au fil du temps).
Je voulais récemment créer un objet (semblable à JQuery) et je suis tombé sur cette question. Alors voici ma réponse: p>
p>
// dummy text element
var p = document.createElement("p");
p.innerText = "Lorem ipsum...";
// jQuery-like object
var CustomObject = function (element) {
return new CustomObject.prototype.init(element);
};
// constructor
CustomObject.prototype.init = function (element) {
this.el = element;
this.text = element.innerText;
};
// instance methods
CustomObject.prototype.log = function () {
console.log(this.text);
// by returning "this" at the end of instance methods
// we make these methods chainable
return this;
};
CustomObject.prototype.add2body = function (delay) {
document.body.appendChild(this.el);
return this;
};
// all the instance methods are added to CustomObject, not to CustomObject.init (constructor)
// calling CustomObject() returns a CustomObject.init object, not CustomObject object
// so by default, instance methods are not accessible
// to fix this, you need to assign the prototype of CustomObject to CustomObject.prototype.init
CustomObject.prototype.init.prototype = CustomObject.prototype;
// testing
var obj = CustomObject(p).add2body().log();
Test (...) CODE> n'est pas le même queNouveau test (...) code>. :)J'ai écrit un article décrivant le concept de création de ce type de bibliothèque simple: DFSQ.INFO/ Site / lecture / écriture-votre-propre-jQuery
Voir ma réponse pour Simple bibliothèque JavaScript comme JQuery