代理模式是爲一個對象提供一個代用品或佔位符,以便控制對它的訪問。 下面就介紹最經常使用的幾種場景html
例如做爲孩子咱們總但願他健康成長,在成長路上遇到的煩惱會被家長解決,這樣來看其實就是保護代理,下面用一段僞代碼來實現。vue
function Children() {
this.knowledge = [];
}
Children.prototype.Study = function(content) {
// ...學習,增長知識
this.knowledge.push(content);
};
var Parent = (function() {
var small = new Children();
return {
knowledge: function(content) {
if (content === "bad") {
// 壞的,過濾掉
} else {
small.Study(content);
}
}
};
})();
複製代碼
上面用僞代碼的形式來實現了一個保護例子,不過你可能會困惑,這樣不是畫蛇添足麼,咱們徹底能夠在Children
內部實現,不過這樣作jquery
緩存代理是很實用的一個例子,例如一個階乘函數
,計算 n 的階乘,最多須要保存 n 個調用記錄,咱們可能這樣寫緩存
function factorial(n) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
factorial(5); // 120
複製代碼
不過若是重複計算 5 或者 10,很明顯形成了屢次浪費,這個時候就可使用代理,把結果緩存下來,若是存在就直接返回。dom
function next(n, total) {
if (n === 1) return 1;
return n * factorial(n - 1);
}
var factorial = (function() {
var obj = {};
return function(v) {
if (obj[v]) {
return obj[v];
}
obj[v] = next(v);
return obj[v];
};
})();
factorial(5); // 120
factorial(5); // 120
複製代碼
上面就將結果緩存了下來,除此以外還能夠引用在異步請求中能夠節省加載的時間。異步
上面簡單介紹了兩種模式,實際上還有不少,好比虛擬代理、遠程代理、防火牆代理等,不過這裏不作介紹了,下面看看使用場景。函數
jquery
基於鏈式調用,好比$('.a').html('').text('')
,不過你會不會很好奇,$()
調用的時候它是怎麼記錄這個值的呢,每次調用$()
存儲的 dom 都不相同,實際上它就是借用了代理模式,這裏直接貼代碼了學習
function Jquery(dom) {
this.dom = dom;
}
// 代理者
function $(dom) {
return new Jquery(dom);
}
$.prototype = Jquery.prototype = {
// 只作演示,不涉及具體代碼
html() {
return this;
},
text() {
return this;
}
};
$(".a")
.html("")
.text("");
複製代碼
咱們在使用 vue 的時候給定了配置項data
,它是一個對象,裏面的屬性會被 vue 響應式處理,咱們能夠經過this.
的方式來簡單訪問,也是用了代理模式,下面就用一段僞 vue 代碼來講明ui
class Mvvm {
constructor(option = {}) {
this.$option = option;
this._data = option.data || {};
// 代理數據
for (const name in this._data) {
Object.defineProperty(this, name, {
configurable: true,
enumerable: true,
get() {
return this._data[name];
},
set(v) {
return (this._data[name] = v);
}
});
}
}
}
export default Mvvm;
複製代碼
能夠複製上面代碼,本身簡單試下。this