《你不知道的JS(中卷)》行为委托
Posted lalal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《你不知道的JS(中卷)》行为委托相关的知识,希望对你有一定的参考价值。
六、行为委托:
? 总结第五章,JS中的[[Prototype]]机制就是 对象之间的关联关系。
一)、面向委托的设计:
? 想要学习更直观的使用[[Prototype]],必须认识到它代表了一种 不同于类的设计模式。
1、类理论:
? 类设计模式鼓励你在继承时使用方法重写(和多态),子类的许多行为可以先“抽象”到父类然后再用子类进行特殊化(重写)。
? 例:
? 父类Task,定义所有任务都有的行为。子类XYZ、ABC继承Task,并添加一些特殊的行为来处理对应的任务。
2、委托理论:
? 相比面向类(面向对象,OOP),这种编码风格称为对象关联,(OLOO, objects linked to other objects)。
? 例:
? 定义一个Task对象,包含所有任务都可以使用的具体行为。接着对于每个任务(XYZ、ABC)都定义一个对象来存储对应的数据和行为。你会把特定的任务对象都关联到Task功能对象上,让它们在需要的时候进行委托。
-
在[[Prototype]]委托中最好把状态保存在委托者(XYZ、ABC)而不是委托目标(Task)上。
-
该设计模式要求尽量少使用容易被重写的通用方法名,提倡使用更有描述性的方法名,尤其是要写清相应对象行为的类型。
-
在API接口的设计中,委托最好在内部实现,不要直接暴露出去。
? 委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象(Task)。这是一种极其强大的设计模式,和父类、子类、继承、多态等概念完全不同。在你的脑海中 对象并不是按照父类到子类的关系垂直组织的,而是通过任意方向的委托关联并排组织的。
1)、互相委托(禁止):
? 你无法在两个或两个以上互相(双向)委托的对象之间创建循环委托。
2)、调试:
? 对象关联风格的代码中,不需要关注谁“构造了”对象,浏览器调试中“构造函数名称”的跟踪没有意义。
3、比较思维模型:
(“原型”)面向对象风格:
function Foo(who) {
this.me = who;
}
Foo.prototype.identify = function () {
return "I am " + this.me;
};
function Bar(who) {
Foo.call(this, who);
}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.speak = function () {
alert("Hello," + this.identify() + ".");
};
var b1 = new Bar("b1");
var b2 = new Bar("b2");
b1.speak();
b2.speak();
对象关联风格:
Foo = {
init: function (who) {
this.me = who;
},
identify: function () {
return "I am " + this.me;
}
};
Bar = Object.create(Foo);
Bar.speak = function () {
alert("Hello, " + this.identify() + ".");
};
var b1 = Object.create(Bar);
b1.init("b1");
var b2 = Object.create(Bar);
b2.init("b2");
b1.speak();
b2.speak();
? 可以明显看出,下面的代码更加简洁。我们只是把对象关联起来,并不需要那些既复杂又令人困惑的模仿类的行为(构造函数、原型以及new)。
二)、类与对象:
? 以Web开发中非常典型的前端常见:创建UI控件为例。
1、控件“类”:
? ES6中的语法糖“class”可以极大地改善丑陋地显式伪多态。
2、委托控件对象:
- 使用类构造函数,需要在同一个步骤中实现构造和初始化。在许多情况下依照对象关联模式,把这两步分开更灵活。
三)、更简洁的设计:
四)、更好的语法:
? ES6中引入class关键字,可以更简洁地定义类方法。同时在ES6中可以在任意对象的字面形式中使用 简洁方法声明。但是有一个缺点:自我引用(递归、事件(解除)绑定,等等)更难。
五)、内省:
? 内省就是检查实例的类型。类实例的自省主要目的是通过创建方式来判断对象的结构和功能。
JS中可以使用instanceof进行自省,也可以利用 鸭子类型:
if (a1.something) {
a1.something();
}
- 当判断a1具有something()方法后,就可以调用该方法。
- ES6的Promise就是典型的“鸭子类型”。
六)、小结:
? 行为委托是一种设计模式,认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。
? 对象关联是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。
以上是关于《你不知道的JS(中卷)》行为委托的主要内容,如果未能解决你的问题,请参考以下文章