为了更好地学习如何更直观地使用 [[Prototype]] ,我们必须认识到它代表的是一种不同
于类的设计模式。
1.1 类理论
假设我们需要在软件中建模一些类似的任务(“XYZ”、“ABC”等)。
如果使用类,那设计方法可能是这样的:定义一个通用父(基)类,可以将其命名为
Task ,在 Task 类中定义所有任务都有的行为。接着定义子类 XYZ 和 ABC ,它们都继承自
Task 并且会添加一些特殊的行为来处理对应的任务。
非常重要的是,类设计模式鼓励你在继承时使用方法重写(和多态),比如说在 XYZ 任务
中重写 Task 中定义的一些通用方法,甚至在添加新行为时通过 super 调用这个方法的原始
版本。你会发现许多行为可以先“抽象”到父类然后再用子类进行特殊化(重写)。
class Task {
id;
// 构造函数 Task()
Task(ID) { id = ID; }
outputTask() { output( id ); }
}
class XYZ inherits Task {
label;
// 构造函数 XYZ()
XYZ(ID,Label) { super( ID ); label = Label; }
outputTask() { super(); output( label ); }
}
class ABC inherits Task {
// ...
}
1.2 委托理论
现在我们试着来使用委托行为而不是类来思考同样的问题
下面是推荐的代码形式,非常简单:
Task = {
setID: function(ID) { this.id = ID; },
outputID: function() { console.log( this.id ); }
};
// 让 XYZ 委托 Task
XYZ = Object.create( Task );
XYZ.prepareTask = function(ID,Label) {
this.setID( ID );
this.label = Label;
};
XYZ.outputTaskDetails = function() {
this.outputID();
console.log( this.label );
};
// ABC = Object.create( Task );
// ABC ... = ...
在这段代码中, Task 和 XYZ 并不是类(或者函数),它们是对象。 XYZ 通过 Object.
create(..) 创建,它的 [[Prototype]] 委托了 Task 对象。
委托行为意味着某些对象( XYZ )在找不到属性或者方法引用时会把这个请求委托给另一
个对象( Task )。
这是一种极其强大的设计模式,和父类、子类、继承、多态等概念完全不同。在你的脑海中
对象并不是按照父类到子类的关系垂直组织的,而是通过任意方向的委托关联并排组织的。
网友评论