Heim >Web-Frontend >js-Tutorial >Lernen Sie JavaScript-Entwurfsmuster – Dekorateurmuster_Javascript-Fähigkeiten

Lernen Sie JavaScript-Entwurfsmuster – Dekorateurmuster_Javascript-Fähigkeiten

WBOY
WBOYOriginal
2016-05-16 15:19:191298Durchsuche

Manchmal möchten wir nicht, dass eine Klasse von Natur aus groß ist und viele Verantwortlichkeiten gleichzeitig enthält. Dann können wir das verzierte Muster verwenden.
Das Dekorationsmuster kann einem Objekt dynamisch einige zusätzliche Verantwortlichkeiten hinzufügen, ohne andere von dieser Klasse abgeleitete Objekte zu beeinträchtigen.
Das dekorierte Muster bettet ein Objekt in ein anderes Objekt ein, was tatsächlich der Umhüllung dieses Objekts durch ein anderes Objekt entspricht und so eine Verpackungskette bildet.

1. Fügen Sie der Funktion einige zusätzliche Funktionen hinzu, ohne die ursprüngliche Funktion zu ändern

1. Speichern Sie das Originalzitat

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

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

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

Frage:
(1) Zwischenvariablen
müssen gepflegt werden (2) Möglicherweise besteht das Problem, dass dies gekapert wird
Im Beispiel von window.onload gibt es solche Probleme nicht, da beim Aufruf der gewöhnlichen Funktion _onload diese ebenfalls auf window verweist, genau wie beim Aufruf von window.onload.

2. Dies wurde gekapert:

var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById(id);
}

return _getElementById(id); // 报错“Uncaught TypeError: Illegal invocation”

Da _getElementById eine globale Funktion ist, zeigt diese beim Aufruf der globalen Funktion auf das Fenster, und in document.getElementById wird erwartet, dass sie auf das Dokument zeigt.

3. Lösen Sie das Problem der Entführung:

var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById.call(document, id);
}

2. Verwenden Sie AOP, um Funktionen zu dekorieren

/* 让新添加的函数在原函数之前执行(前置装饰)*/
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. Vermeiden Sie die Kontamination von Prototypen

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. Beispiel – Plug-in-Formularvalidierung

In Kombination mit der [Formularvalidierung] in „Lernen von JavaScript-Entwurfsmustern – Strategiemuster“ und der Anwendung von Ajax zur Übermittlung der Datenüberprüfung ist der Effekt großartig!

Ändern Sie die obige Vorher-Methode

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. Decorator-Modus und Proxy-Modus

Ähnliche Punkte: Beide Muster beschreiben, wie ein gewisser Grad an indirekter Referenz für ein Objekt bereitgestellt wird. Ihre Implementierungsteile behalten eine Referenz auf ein anderes Objekt bei und senden Anforderungen an dieses Objekt.
Unterschied:
(1) Proxy-Modus: Wenn der direkte lokale Zugriff unpraktisch ist oder die Anforderungen nicht erfüllt, stellen Sie einen Ersatz für diese Ontologie bereit. Definieren Sie Schlüsselfunktionen lokal, und der Agent gewährt oder verweigert den Zugriff darauf oder führt einige zusätzliche Dinge aus, bevor er auf die Ontologie zugreift. (Es macht immer noch das Gleiche wie der Hauptteil)
(2) Dekorationsmodus: Verhaltensweisen dynamisch zu Objekten hinzufügen. (Sie können zu Beginn nicht alle Funktionen des Objekts bestimmen und dem Objekt tatsächlich neue Verantwortlichkeiten und Verhaltensweisen hinzufügen)

Ich hoffe, dass dieser Artikel für alle hilfreich ist, die JavaScript-Programmierung lernen.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn