一 目录
不折腾的前端,和咸鱼有什么区别
目录 |
---|
一 目录 |
二 前言 |
三 面向对象 |
3.1 封装 |
3.2 继承 |
3.2.1 ES5 写法 |
3.2.2 ES6 写法 |
3.3 多态 |
3.3.1 ES5 写法 |
3.3.2 ES6 写法 |
四 设计准则 |
五 工厂模式 |
5.1 ES5 写法 |
5.2 ES6 写法 |
5.3 小结 |
六 单例模式 |
6.1 ES5 写法 |
6.2 ES6 写法 |
七 代理模式和中介者模式 |
7.1 代理模式 |
7.2 中介者模式 |
7.3 小结 |
八 公布订阅模式 |
8.1 观察者模式举例 |
8.2 Object.defineProperty 和 Proxy |
8.3 小结 |
九 参考文献 |
二 前言
返回目录
设计模式是一门学识,它外面有 22+ 品种的设计模式。
淡淡难过:你只管学,过几个月忘了回来再看看你还懂不懂。
前端面试中,常见的你能够答复的设计模式如下:
设计模式 | 形容 | 例子 |
---|---|---|
单例模式 | 一个类只能结构出一个惟一实例 | Redux/Vuex 的 Store |
工厂模式 | 对创建对象逻辑的封装 | jQuery 的 $(selector) |
观察者模式 | 当一个对象被批改时,会主动告诉它的依赖对象 | Redux 的 subsrcibe 、Vue 的双向绑定 |
装璜器模式 | 对类的包装,动静地扩大类的性能 | React 的高阶组件、ES7 装璜器 |
适配器模式 | 兼容新旧接口,对类的包装 | 封装旧 API |
代理模式 | 管制对象的拜访 | 事件代理、ES6 的 Proxy |
当然,如果你还理解其余,那就更好了~
三 面向对象
返回目录
在开始温习设计模式之前,咱们回顾下面向对象。
什么是面向对象,咱们能够和面向过程比对一下:
-
面向过程 :关注的是过程中的每一个环节
- 吃蛋炒饭(独身狗版):买鸡蛋 → 买米 → 蒸米 → 炒蛋 → 炒米 → 混合 → 搅拌 → 蛋炒饭
-
面向对象 :关注的是让对象做事件
- 吃蛋炒饭(情侣版):找一个对象,做蛋炒饭,你吃蛋炒饭
事实可能不会扎你的心,然而 jsliang 会。
jsliang 也是独身汪,所以扎你们前先扎了本人,不慌,一起扎心
面向对象(Object Oriented Programming,简称 OOP),是一种编程开发思维。
它将真实世界各种简单的关系,形象为一个个对象,而后由对象之间的分工与单干,实现对真实世界的模仿。
- 事实需要(盖大楼)
- 须要哪些对象(设计师、搬运工、砌墙师、木匠、导购…)
- 分工与单干
- 实现我的项目
这就好比你要实现一个我的项目,你能够会配置 Webpack + Babel,并且用上 React 和 Ant Design。
那么 Webpack 由什么组成呢,你又能够将其拆离开,填充一个一个 loader
和 plugin
,最终由一个个小组件组合成一个我的项目。
简略来说:面向对象关怀的不是过程,关怀的是哪个局部找谁来实现。
面向对象有三大个性: 封装、根底和多态 ,上面咱们一一介绍。
3.1 封装
返回目录
假如咱们须要判断指标类型:
面向过程写法
// 明天 A 找你判断下类型
const A = 'jsliang';
const AType = Object.prototype.toString.call(A);
console.log(AType); // [object String]
// 今天 B 找你判断下类型
const B = 25;
const BType = Object.prototype.toString.call(B);
console.log(BType); // [object Number]
// 先天 C 找你判断下类型
const C = {obj: 'girl'};
const CType = Object.prototype.toString.call(C);
console.log(CType); // [object Object]
这就好比明天亲戚 A 找你办事,今天亲戚 B 找你办事,先天亲戚 C 找你办事,然而他们要你帮忙做的是查一下某某明星。
烦不烦,为啥别家亲戚是介绍相亲,你家亲戚是介绍明星。
于是你想了个法子:
面向对象写法
// 判断类型
const getType = (obj) => Object.prototype.toString.call(obj);
// 明天 A 找你判断下类型
const A = 'jsliang';
console.log(getType(A)); // [object String]
// 今天 B 找你判断下类型
const B = 25;
console.log(getType(B)); // [object Number]
// 先天 C 找你判断下类型
const C = {obj: 'girl'};
console.log(getType(C)); // [object Object]
当你让亲戚用你写的“千度”软件去查找之后,世界霎时宁静了,祝贺你实现了宅男的个性的保护。
咳咳,话回正题,其实这就是封装了。
想必看到这里小伙伴也不会生疏,日常工作中,碰到呈现屡次的代码,个别都会采取封装形式将代码抽取进去。
封装的益处 :封装的劣势在于定义只能够在类外部进行对属性的操作,内部无奈对这些属性指手画脚,要想批改,也只能通过你定义的封装办法。
3.2 继承
返回目录
到职期间,jsliang 每天晚上因为找不到工作而疲乏的时候,都会空想我老爸是千万富翁,其实让我工作只是为了让我能接受考验,最初是要回家继承资产的~
没错,这个继承和你想的继承差不多,就是有一个办法 Father
,而后 Children
继承 Father
账目上的内容。
留神是账目上,就是说 Father
的动态属性和静态方法并不会继承,就好比你继承资产就够了,不须要继承父辈的不良嗜好(抽烟喝酒)。
颤抖有益,咱看代码。
3.2.1 ES5 写法
返回目录
ES5 写继承的话,这里来一个手写继承的形式吧,用的是 寄生组合式继承 。
const Father = function (name, like) {
this.name = name;
this.like = like;
this.money = 10000000;
};
Father.prototype.company = function() {console.log(`${this.name} 有 ${this.money} 元 `);
}
const Children = function (name, like) {Father.call(this);
this.name = name;
this.like = like;
}
Children.prototype = Object.create(Father.prototype);
Children.prototype.constructor = Children;
const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: "jsliang", like: "学习", money: 10000000}
jsliang.company(); // jsliang 有 10000000 元
这是一个面试考点,就是考你能不能手写继承。
当然还有其余的继承形式,这是 jsliang 找到的一个较为欠缺的继承办法。
3.2.2 ES6 写法
返回目录
class Father {constructor(name, like) {
this.name = name;
this.like = like;
this.money = 10000000;
}
company() {console.log(`${this.name} 有 ${this.money} 元 `);
}
// 静态方法并不会继承,并且能够通过类名调用
static smoke() {console.log(`${this.name} 喜爱抽烟 `);
}
}
Father.smoke(); // Father 喜爱抽烟
class Children extends Father {constructor(name, like) {super();
this.name = name;
this.like = like;
}
}
const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: "jsliang", like: "学习", money: 10000000}
jsliang.company(); // jsliang 有 10000000 元
jsliang.smoke(); // TypeError: jsliang.smoke is not a function
特地揭示 :继承会继承父类的实例属性和实例办法,并不会继承动态属性和静态方法,并且静态方法只能通过类名去调用。
继承的益处 :继承缩小了代码的冗余,省略了很多反复代码,开发者能够从父类底层定义所有子类必须有的属性和办法,以达到耦合的目标;
3.3 多态
返回目录
多态,能够简略了解为继承过去并对其有本人的了解。
多态具体表现为办法重载和办法重写:
- 办法重载 :重载是指不同的函数应用雷同函数名,然而函数的参数个数或者类型不同。调用的时候依据函数的参数来辨别不同的函数。
- 办法重写 :重写(也叫笼罩)是指派生类中从新对基类中的虚函数从新实现。即函数名和参数都一样,只是函数的实现体不一样。
上面咱们来个多态之 办法重写 的 ES5 和 ES6 写法。
3.3.1 ES5 写法
返回目录
const Father = function (name, like) {
this.name = name;
this.like = like;
this.money = 10000000;
};
Father.prototype.company = function() {console.log(`${this.name} 有 ${this.money} 元 `);
}
const Children = function (name, like) {Father.call(this);
this.name = name;
this.like = like;
this.money = 10000;
}
Children.prototype = Object.create(Father.prototype);
Children.prototype.constructor = Children;
Children.prototype.company = function() {console.log(`${this.name} 有 ${this.money} 元 `);
}
const father = new Father('jsliang 的老爸', '学习');
console.log(father); // Father {name: 'jsliang 的老爸', like: '学习', money: 10000000}
father.company(); // jsliang 的老爸 有 10000000 元
const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: 'jsliang', like: '学习', money: 10000}
jsliang.company(); // jsliang 有 10000 元
3.3.2 ES6 写法
返回目录
class Father {constructor(name, like) {
this.name = name;
this.like = like;
this.money = 10000000;
}
company() {console.log(`${this.name} 有 ${this.money} 元 `);
}
}
class Children extends Father {constructor(name, like) {super();
this.name = name;
this.like = like;
this.money = 10000;
}
company() {console.log(`${this.name} 有 ${this.money} 元 `);
}
}
const father = new Father('jsliang 的老爸', '抽烟');
console.log(father); // Father {name: 'jsliang 的老爸', like: '抽烟', money: 10000000}
father.company(); // jsliang 的老爸 有 10000000 元
const jsliang = new Children('jsliang', '学习');
console.log(jsliang); // Children {name: 'jsliang', like: '学习', money: 10000}
jsliang.company(); // jsliang 有 10000 元
果然做“工程师”是没有前途的,做梦才是。
你看要个点赞和 Github star,弹幕评论区全是“下次肯定”。
硬核广告,如果小伙伴须要分割 jsliang,能够到 GitHub 首页找到联系方式:
- Github
多态的益处 :多态实现了办法的个性化,不同的子类依据具体情况能够实现不同的办法,光有父类定义的办法不够灵便,遇见非凡情况就顾此失彼了。
四 设计准则
返回目录
设计模式有 6 大准则:繁多职责准则、里氏替换准则、依赖倒置准则、接口隔离准则、迪米特准则、凋谢关闭准则。
当然,咱们不是“职业”的,咱们就是面向面试的,所以记住两个准则即可:
- 繁多职责准则 :一个类只负责一个性能畛域中的相应职责。或者:就一个类而言,只有一个引起它变动的起因。
- 凋谢关闭准则 :外围的思维是软件实体(类、模块、函数等)是可扩大的、但不可批改的。也就是说,对拓展是凋谢的,对批改是关闭的。
上面咱们开始一一介绍设计模式。
五 工厂模式
返回目录
在日常生活中,咱们晓得有果糖工厂、塑料工厂。
而设计模式中的工厂模式,也是如此。
工厂模式是 JavaScript 中最罕用的一种用于创建对象的设计模式,其外围就是将逻辑封装在一个函数中不裸露创建对象的具体逻辑。
5.1 ES5 写法
返回目录
const Person = function() {const [name, age, sex] = [...arguments];
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = () => {console.log(` 我叫 ${this.name},性别 ${this.sex},往年 ${this.age}`);
}
};
const p1 = new Person('jsliang', 25, '男');
const p2 = new Person('靓女', 25, '女');
p1.sayName(); // 我叫 jsliang,性别 男,往年 25
p2.sayName(); // 我叫 靓女,性别 女,往年 25
5.2 ES6 写法
返回目录
class Person {constructor(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
sayName() {console.log(` 我叫 ${this.name},性别 ${this.sex},往年 ${this.age}`);
}
}
const p1 = new Person('jsliang', 25, '男');
const p2 = new Person('靓女', 25, '女');
p1.sayName(); // 我叫 jsliang,性别 男,往年 25
p2.sayName(); // 我叫 靓女,性别 女,往年 25
5.3 小结
返回目录
工厂模式是为了解决多个相似对象申明的问题,也就是为了解决实列化对象产生反复的问题。
工厂模式的优缺点如下:
- 长处 :能解决多个类似的问题。
- 毛病 :不能晓得对象辨认的问题(对象的类型不晓得)
六 单例模式
返回目录
单例模式即一个类只能结构出惟一实例,单例模式的意义在于共享、惟一,Redux/Vuex 中的 Store
、jQuery 的 $
或者业务场景中的购物车、登录框都是单例模式的利用。
6.1 ES5 写法
返回目录
const Single = function (name, password) {
this.name = name;
this.password = password;
};
Single.prototype.login = (name, password) => {if (!this.only) {this.only = new Single(name, password);
}
return this.only;
};
let user1 = new Single().login('jsliang', '123456');
let user2 = new Single().login('zhazhaliang', '654321');
console.log(user1 === user2); // true
console.log(user1); // Single {name: 'jsliang', password: '123456'}
console.log(user2); // Single {name: 'jsliang', password: '123456'}
6.2 ES6 写法
返回目录
class SingletonLogin {constructor(name, password) {
this.name = name;
this.password = password;
}
static getInstance(name, password) {
// 判断对象是否曾经被创立, 若创立则返回旧对象
if (!this.instance) {this.instance = new SingletonLogin(name, password);
}
return this.instance;
}
}
let obj1 = SingletonLogin.getInstance('jsliang', '123456')
let obj2 = SingletonLogin.getInstance('zhazhaliang', '654321')
console.log(obj1 === obj2) // true
console.log(obj1) // SingletonLogin {name: 'jsliang', password: '123456'}
console.log(obj2) // SingletonLogin {name: 'jsliang', password: '123456'}
七 代理模式和中介者模式
返回目录
上面咱们将代理模式和中介者模式:
- 代理模式 :代理模式强调的是个体。将原类(原办法体)进行封装,客户端只须要与代理进行交换,代理就是原类的一个替身。简而言之就是用一个对象代表另外一个对象。
- 中介模式 :中介模式强调的是相互独立。定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不须要显示地互相援用,从而使其耦合性涣散,而且能够独立地扭转他们之间的交互。
OK,上面咱们通过代码了解下代理模式和中介者模式吧~
7.1 代理模式
返回目录
代码模式就是:
jsliang 要给心动女孩送花,而后 jsliang 不好意思,所以他解脱他的好哥们帮忙送花,这个代理人就是好哥们。
// 心动女孩
const Girl = function() {
this.name = '心动女孩';
this.get = (person, gift) => {console.log(`${person} 送给 ${this.name} ${gift}`);
};
}
// jsliang
const JSLiang = function() {
this.name = 'jsliang';
this.send = () => {return '99 朵玫瑰';}
}
// 好哥们
const Friend = function(getUser) {this.getUser = new getUser();
this.jsliang = new JSLiang();
this.run = () => {this.getUser.get(this.jsliang.name, this.jsliang.send());
}
};
// 好哥们帮忙给不同妹子送礼物
const friend = new Friend(Girl);
friend.run(); // jsliang 送给 心动女孩 99 朵玫瑰
哎,形象全没,jsliang 见一个爱一个,好哥们不得跑断腿,哈哈。
代理模式实用场景 :
代理模式的实用场景是图片的预加载,在预加载过程中,图片未加载结束之前,用一个 loading
作为图片的占位符,期待加载结束之后再进行赋值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> 代理模式 </title>
</head>
<body>
<div class="animation"> 动画元素 </div>
<script>
window.onload = function () {var myImage = (function () {var imgNode = document.createElement("img");
document.body.appendChild(imgNode);
return {setSrc: function (src) {imgNode.src = src;}
}
})();
// 代理模式
var ProxyImage = (function () {var img = new Image();
img.onload = function () {myImage.setSrc(this.src);
};
return {setSrc: function (src) {myImage.setSrc("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603709264332&di=f6f8e48c1c88bf640aac9899df98a97c&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fq_mini%2Cc_zoom%2Cw_640%2Fimages%2F20171107%2F643ceb1031394c5887d3509b31878c52.gif");
setTimeout(() => {img.src = src;}, 3000);
}
}
})();
// 调用形式
ProxyImage.setSrc("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3592308877,3684082784&fm=26&gp=0.jpg");
};
</script>
</body>
</html>
7.2 中介者模式
返回目录
那么什么是中介者模式呢?
就是当好哥们想赚外快的时候,想起他已经帮 jsliang 跑过腿,那么他也能够帮其他人跑腿啊,于是好哥们变成了中间商,成立了快递公司。
// 心动女孩
const Girl = function() {
this.name = '心动女孩';
this.get = (person, gift) => {console.log(`${person} 送给 ${this.name} ${gift}`);
};
}
// jsliang
const JSLiang = function() {
this.name = 'jsliang';
this.send = () => {return '99 朵玫瑰';}
}
// 快递公司
const Express = function(postUser, getUser) {this.postUser = new postUser();
this.getUser = new getUser();
this.run = () => {this.getUser.get(this.postUser.name, this.postUser.send());
}
};
// 快递员
const courier = new Express(JSLiang, Girl);
courier.run(); // jsliang 送给 心动女孩 99 朵玫瑰
很简略嘛,假如 jsliang 喜爱的女孩不在广州,那么就须要他人“帮忙”将礼物送给异地 girl。
而这种模式,就是中介者模式,作为一个中间人传递信息。
从中能够看出代理模式的益处:
- 代理对象能够代替本体被实例化,并使其能够被近程拜访
- 能够把本体实例化推延到真正须要的时候。
当然,有好就有坏,在代码中应用代理模式,这个中介会承当较多的责任,一旦中介(快递员)病了,那么你的花就送达不了了。
同样,事实中,如果你真喜爱那妹子,还是当面去送吧,没听过“每天收到花的女孩最初和快递员结婚了么!”
中介者模式实用场景 :
var goods = {
// 手机库存
"red|32G": 3,
"red|64G": 1,
"blue|32G": 7,
"blue|32G": 6,
};
// 中介者
var mediator = (function () {var colorSelect = document.getElementById("colorSelect");
var memorySelect = document.getElementById("memorySelect");
var numSelect = document.getElementById("numSelect");
return {changed: function (obj) {switch (obj) {
case colorSelect:
// TODO
break;
case memorySelect:
// TODO
break;
case numSelect:
// TODO
break;
}
},
};
})();
colorSelect.onchange = function () {mediator.changed(this);
};
memorySelect.onchange = function () {mediator.changed(this);
};
numSelect.onchange = function () {mediator.changed(this);
};
7.3 小结
返回目录
这里将代理模式和中介者模式放在一块,置信小伙伴们也看到了,是有缘故的。
然而理论工作中会不会罕用代理模式和中介者模式,jsliang 不晓得,因为真没试过,可能某些场景试过,然而不会往这方面想。
当前工作有机会再注意注意吧,至于面试中有没可能问?这里也不晓得,因为这是非热点,小伙伴们理解理解即可~
八 公布订阅模式
返回目录
公布 - 订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象产生扭转时,所有依赖于它的对象都将失去告诉。
看完定义有点懵?
现实生活中的公布 - 订阅模式,就好比 jsliang 在网上看中一双鞋子,然而没货了,于是点击(订阅)了卖家的发货告诉。等卖家有货之后,所有点击(订阅)了发货告诉的买家,都会看到告诉。
公布 - 订阅模式的优缺点:
- 长处
- 反对简略的播送通信。当对象状态产生扭转时,会主动告诉曾经订阅过的对象,例如下面的举例。
- 发布者与订阅者的耦合性升高。我是卖家我并不关怀有多少人订阅了,我只有到货的时候,将货物数量更改下就行了。
- 毛病
- 耗时耗内存。创立订阅者须要耗费肯定的工夫和内存
- 适度应用不好保护。
OK,说了那么多,咱们举个代码小例子,而后讲讲 Vue 中的 Object.defineProperty
和 Proxy
应用。
8.1 观察者模式举例
返回目录
// 定义发布者
const seller = {};
// 缓存列表:寄存订阅者的回调函数
seller.buyerList = [];
// 订阅办法
seller.listen = (user, fn) => {
// 如果有人订阅了,那就将它寄存到缓存列表中
seller.buyerList.push(fn);
console.log(` 敬爱的 ${user},你曾经订阅了新鞋公布 `);
}
// 公布信息
seller.trigger = () => {
const buyerList = seller.buyerList;
for (let i in buyerList) {if (buyerList.hasOwnProperty(i)) {buyerList[i].call(this);
}
}
}
const buyer1 = seller.listen('jsliang', () => console.log('色彩是彩色,尺码是 43 码')); // 敬爱的 jsliang,你曾经订阅了新鞋公布
const buyer2 = seller.listen('zhazhaliang', () => console.log('色彩是红色,尺码是 44 码')); // 敬爱的 zhazhaliang,你曾经订阅了新鞋公布
// 假如 2 秒后到货
setTimeout(() => {seller.trigger();
}, 2000);
// 色彩是彩色,尺码是 43 码
// 色彩是红色,尺码是 44 码
这样就实现了简略的公布 - 订阅模式,如果卖家有不同商品,两个用户别离关注两个不同商品要怎么实现呢?小伙伴们能够思考思考。
8.2 Object.defineProperty 和 Proxy
返回目录
在 Vue 2.0 版本,咱们通过 Object.defineProperty
来察看数据:
const person = {
name: 'jsliang',
age: 25,
};
Object.keys(person).forEach((key) => {
Object.defineProperty(person, key, {
enumerable: true,
configurable: true,
get: () => {console.log('get');
},
set: (newName) => {console.log(newName);
},
});
});
person.name = 'zhazhaliang'; // zhazhaliang
console.log(person); // {name: [Getter/Setter], age: [Getter/Setter] }
其中:
enumerable
:对象属性是否可通过for-in
循环,false
为不可循环,默认值为true
。configurable
:是否应用 ·、是否需改属性个性、或是否批改拜访器属性,false
为不可从新定义,默认值为true
。
那么,咱们再来看看 Proxy
:
const queuedObserver = new Set();
const observe = fn => queuedObserver.add(fn);
const observeable = obj => new Proxy(obj, {set});
const set = function(target, key, value, receiver) {const result = Reflect.set(target, key, value, receiver);
queuedObserver.forEach(observer => observer());
return result;
};
const person = observeable({
name: 'jsliang',
age: 25,
});
const print = () => {console.log(` 姓名:${person.name},年龄:${person.age}`);
}
observe(print);
person.name = 'zhazhaliang'; // 姓名:zhazhaliang,年龄:25
那么,为什么 Vue 3.0 要换成 Proxy
呢?
留神听讲,这是面试题~
Object.defineProperty
毛病:
- 不能监听数组变动
- 必须遍历对象每个属性
而 Proxy
的指标是对象,这样就省去了属性的遍历。
至于更深刻的理解,譬如如何在页面中敲一个,让页面和数据绑定,这里就不颤抖了,感兴趣的小伙伴们能够看 jsliang 另一个库:
- all-for-one 你感兴趣的这里全都有
8.3 小结
返回目录
须要斧正一点的是,ES6 Proxy
在模式上属于代理模式。
日常工作中,常见的观察者模式有:
Promise
- Node 的
EventEmitter
事件监听器 - Vue 的
Watch
申明周期钩子
九 参考文献
返回目录
本系列参考 14 篇文章。
- [x] 设计模式【浏览倡议:1h】
- [x] Javascript 罕用的设计模式详解【浏览倡议:1h】
- [x] JavaScript 设计模式【浏览倡议:20min】
- [x] JavaScript 中常见设计模式整顿【浏览倡议:1h】
- [x] JavaScript 常见设计模式解析【浏览倡议:20min】
- [x] 深刻 JavaScript 设计模式,从此有了优化代码的理论依据【浏览倡议:30min】
- [x] 设计模式之美 - 前端【浏览倡议:1h】
- [x] 公布订阅模式,在工作中它的能量超乎你的设想【浏览倡议:30min】
- [x] 应用原生 JavaScript 构建状态管理系统【浏览倡议:20min】
- [x] 外观模式、代理模式和中介者模式的区别【浏览倡议:1min】
- [x]【设计模式】外观模式 & 代理模式 & 中介者模式的区别【浏览倡议:3min】
- [x] Proxy 与 Object.defineProperty 介绍与比照【浏览倡议:10min】
- [x] Proxy 和 defineProperty 实现数据察看(观察者模式)【浏览倡议:20min】
- [x] Proxy 观察者模式以及 Object.defineProperty 的毛病【浏览倡议:3min】
jsliang 的文档库由 梁峻荣 采纳 常识共享 署名 - 非商业性应用 - 雷同形式共享 4.0 国内 许可协定 进行许可。<br/> 基于 https://github.com/LiangJunrong/document-library 上的作品创作。<br/> 本许可协定受权之外的应用权限能够从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处取得。