Parfois, nous ne voulons pas qu'une classe soit intrinsèquement grande et contienne de nombreuses responsabilités à la fois. Ensuite, nous pouvons utiliser le motif décoré.
Le modèle de décorateur peut ajouter dynamiquement des responsabilités supplémentaires à un objet sans affecter les autres objets dérivés de cette classe.
Le motif décoré intègre un objet dans un autre objet, ce qui équivaut en fait à ce que cet objet soit enveloppé par un autre objet, formant une chaîne d'emballage.
1. Ajoutez quelques fonctions supplémentaires à la fonction sans modifier la fonction d'origine
1. Enregistrez la citation originale
window.onload = function() { console.log(1); }; var _onload = window.onload || function() {}; window.onload = function() { _onload(); console.log(2); }
Question :
(1) Les variables intermédiaires
doivent être conservées
(2) Vous pourriez rencontrer le problème de ce détournement
Dans l'exemple de window.onload, il n'y a pas de problème de ce type car lors de l'appel de la fonction ordinaire _onload, cela pointe également vers window, tout comme lors de l'appel de window.onload.
2. ceci a été détourné :
var _getElementById = document.getElementById; document.getElementById = function(id) { console.log(1); return _getElementById(id); } return _getElementById(id); // 报错“Uncaught TypeError: Illegal invocation”
Parce que _getElementById est une fonction globale, lorsque la fonction globale est appelée, elle pointe vers la fenêtre, et celle-ci dans document.getElementById est censée pointer vers le document.
3. Résolvez ce problème de détournement :
var _getElementById = document.getElementById; document.getElementById = function(id) { console.log(1); return _getElementById.call(document, id); }
2. Utilisez AOP pour décorer les fonctions
/* 让新添加的函数在原函数之前执行(前置装饰)*/ Function.prototype.before = function(beforefn) { var _self = this; return function() { beforefn.apply(this, arguments); // 新函数接收的参数会被原封不动的传入原函数 return _self.apply(this, arguments); }; };
/* 让新添加的函数在原函数之后执行(后置装饰)*/ Function.prototype.after = function(afterfn) { var _self = this; return function() { var ret = _self.apply(this, arguments); afterfn.apply(this, arguments); return ret; }; };
document.getElementById = document.getElementById.before(function() { console.log(1); });
3. Évitez de contaminer les prototypes
var before = function(fn, beforefn) { return function() { beforefn.apply(this, arguments); return fn.apply(this, arguments); }; }; var after = function(fn, afterfn) { return function() { var ret = fn.apply(this, arguments); afterfn.apply(this, arguments); return ret; }; }; document.getElementById = before(document.getElementById, function(){ console.log(1); });
4. Exemple – validation du formulaire de plug-in
Combiné avec la [Validation de formulaire] dans "Apprentissage des modèles de conception JavaScript - Modèle de stratégie" et appliqué ajax pour soumettre la vérification des données, l'effet est génial !
Modifiez la méthode ci-dessus avant
var before = function(fn, beforefn) { return function() { if(beforefn.apply(this, arguments) === false) { // beforefn返回false,直接return,不执行后面的原函数 return; } return fn.apply(this, arguments); }; };
/* 模拟数据验证*/ var validate = function() { if(username === "") { console.log("验证失败!"); return false; } return true; } /* 模拟ajax提交*/ var formSubmit = function() { console.log("提交!!!"); }
username = 1; formSubmit = before(formSubmit, validate); // 提交!!! formSubmit(); username = ""; formSubmit = before(formSubmit, validate); // 验证失败! formSubmit();
5. Mode Décorateur et mode proxy
Points similaires : les deux modèles décrivent comment fournir un certain degré de référence indirecte pour un objet. Leurs parties d'implémentation conservent une référence à un autre objet et envoient des requêtes à cet objet.
Différence :
(1) Mode proxy : lorsque l'accès local direct n'est pas pratique ou ne répond pas aux exigences, proposez un substitut à cette ontologie. Définissez localement les fonctionnalités clés et l'agent y fournit ou refuse l'accès, ou effectue des tâches supplémentaires avant d'accéder à l'ontologie. (Il fait toujours la même chose que le corps principal)
(2) Mode Décorateur : ajoutez dynamiquement des comportements aux objets. (Vous ne pouvez pas déterminer toutes les fonctions de l'objet au début, et réellement ajouter de nouvelles responsabilités et comportements à l'objet)
J'espère que cet article sera utile à tous ceux qui apprennent la programmation JavaScript.