代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。 下面就介绍最经常使用的几种场景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