Maison  >  Article  >  interface Web  >  Exemples détaillés de la différence entre la fonction du modèle de décorateur JavaScript et du modèle de proxy

Exemples détaillés de la différence entre la fonction du modèle de décorateur JavaScript et du modèle de proxy

伊谢尔伦
伊谢尔伦original
2017-07-24 14:36:012012parcourir

Le motif décoré 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.

Ajouter quelques fonctions supplémentaires à la fonction sans modifier la fonction d'origine

1 Enregistrer la référence d'origine


window.onload = function() {
  console.log(1);
};

var _onload = window.onload || function() {};

window.onload = function() {
  _onload();
  console.log(2);
}

Problèmes : (1) Les variables intermédiaires doivent être maintenues
(2) Cela peut être détourné
Dans le exemple de window.onload, il n'y a pas de problème 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 est 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 Lors de l'appel de la fonction globale, cela pointe vers la fenêtre, et dans document.getElementById, cela devrait 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);
}

Décorez la fonction avec AOP


/* 让新添加的函数在原函数之前执行(前置装饰)*/
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);
});

Éviter Prototype de contamination


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);
});

Motif décorateur et motif proxy

Mêmeness : ces deux motifs décrivent tous deux comment fournir un certain degré de référence indirecte pour un objet. Leurs parties d'implémentation conservent toutes une référence à un autre objet et envoient des requêtes à cet objet.

Différences :
(1) Mode proxy : Lorsque l'accès local direct n'est pas pratique ou ne répond pas aux besoins, 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. (Cela fait toujours la même chose que l'ontologie)
(2) Mode Décorateur : Ajoutez dynamiquement des comportements à l'objet. (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)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn