标签:关键字 定义类 类型 cti 找不到 对象关联 调用 多态 cts
? 总结第五章,JS中的[[Prototype]]机制就是 对象之间的关联关系。
? 想要学习更直观的使用[[Prototype]],必须认识到它代表了一种 不同于类的设计模式。
? 类设计模式鼓励你在继承时使用方法重写(和多态),子类的许多行为可以先“抽象”到父类然后再用子类进行特殊化(重写)。
? 例:
? 父类Task,定义所有任务都有的行为。子类XYZ、ABC继承Task,并添加一些特殊的行为来处理对应的任务。
? 相比面向类(面向对象,OOP),这种编码风格称为对象关联,(OLOO, objects linked to other objects)。
? 例:
? 定义一个Task对象,包含所有任务都可以使用的具体行为。接着对于每个任务(XYZ、ABC)都定义一个对象来存储对应的数据和行为。你会把特定的任务对象都关联到Task功能对象上,让它们在需要的时候进行委托。
在[[Prototype]]委托中最好把状态保存在委托者(XYZ、ABC)而不是委托目标(Task)上。
该设计模式要求尽量少使用容易被重写的通用方法名,提倡使用更有描述性的方法名,尤其是要写清相应对象行为的类型。
在API接口的设计中,委托最好在内部实现,不要直接暴露出去。
? 委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象(Task)。这是一种极其强大的设计模式,和父类、子类、继承、多态等概念完全不同。在你的脑海中 对象并不是按照父类到子类的关系垂直组织的,而是通过任意方向的委托关联并排组织的。
? 你无法在两个或两个以上互相(双向)委托的对象之间创建循环委托。
? 对象关联风格的代码中,不需要关注谁“构造了”对象,浏览器调试中“构造函数名称”的跟踪没有意义。
(“原型”)面向对象风格:
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控件为例。
? ES6中的语法糖“class”可以极大地改善丑陋地显式伪多态。
? ES6中引入class关键字,可以更简洁地定义类方法。同时在ES6中可以在任意对象的字面形式中使用 简洁方法声明。但是有一个缺点:自我引用(递归、事件(解除)绑定,等等)更难。
? 内省就是检查实例的类型。类实例的自省主要目的是通过创建方式来判断对象的结构和功能。
JS中可以使用instanceof进行自省,也可以利用 鸭子类型:
if (a1.something) {
a1.something();
}
? 行为委托是一种设计模式,认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。
? 对象关联是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。
标签:关键字 定义类 类型 cti 找不到 对象关联 调用 多态 cts
原文地址:https://www.cnblogs.com/enmac/p/13191410.html