有時我們不希望某個類天生就非常龐大,一次性包含許多職責。那么我們就可以使用裝飾著模式。 
裝飾著模式可以動態地給某個對象添加一些額外的職責,從而不影響這個類中派生的其他對象。 
裝飾著模式將一個對象嵌入另一個對象之中,實際上相當于這個對象被另一個對象包裝起來,形成一條包裝鏈。
一、不改動原函數的情況下,給該函數添加些額外的功能
1. 保存原引用
window.onload = function() {  console.log(1);};var _onload = window.onload || function() {};window.onload = function() {  _onload();  console.log(2);}問題: 
(1)必須維護中間變量 
(2)可能遇到this被劫持問題 
在window.onload的例子中沒有這個煩惱,是因為調用普通函數_onload時,this也指向window,跟調用window.onload時一樣。
2. this被劫持:
var _getElementById = document.getElementById;document.getElementById = function(id) {  console.log(1);  return _getElementById(id);}return _getElementById(id); // 報錯“Uncaught TypeError: Illegal invocation”因為_getElementById是全局函數,當調用全局函數時,this是指向window的,而document.getElementById中this預期指向document。
3. 解決this被劫持:
var _getElementById = document.getElementById;document.getElementById = function(id) {  console.log(1);  return _getElementById.call(document, id);}二、用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);});三、避免污染原型
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);});四、示例 主站蜘蛛池模板: 横山县| 洪湖市| 达拉特旗| 辉县市| 丹凤县| 咸阳市| 河北区| 信宜市| 盐津县| 昭苏县| 瓦房店市| 厦门市| 绥芬河市| 揭西县| 华安县| 宽甸| 双城市| 新源县| 永嘉县| 怀仁县| 北京市| 威海市| 府谷县| 类乌齐县| 岳阳市| 贵德县| 深泽县| 邳州市| 西华县| 莒南县| 浪卡子县| 贵州省| 新兴县| 高平市| 八宿县| 老河口市| 太仓市| 依安县| 漠河县| 和龙市| 河间市|