最近在看JavaScript: The Good Parts,目前为止看的轻松愉快,内容讲的很好。但是到了 Inheritance 一章 Parts
这一节的时候,完全傻眼了,根本不知道它在讲什么东西,求给点提示或者例子,以下是章节内容
Parts
We can compose objects out of sets of parts. For example, we can make a function
that can add simple event processing features to any object. It adds an on method, a
fire method, and a private event registry:
var eventuality = function (that) {
var registry = {};
that.fire = function (event) {
// Fire an event on an object. The event can be either
// a string containing the name of the event or an
// object containing a type property containing the
// name of the event. Handlers registered by the 'on'
// method that match the event name will be invoked.
var array,
func,
handler,
i,
type = typeof event === 'string' ?
event : event.type;
// If an array of handlers exist for this event, then
// loop through it and execute the handlers in order.
if (registry.hasOwnProperty(type)) {
array = registry[type];
for (i = 0; i < array.length; i += 1) {
handler = array[i];
// A handler record contains a method and an optional
// array of parameters. If the method is a name, look
// up the function.
func = handler.method;
if (typeof func === 'string') {
func = this[func];
}
// Invoke a handler. If the record contained
// parameters, then pass them. Otherwise, pass the
// event object.
func.apply(this,
handler.parameters || [event]);
}
}
return this;
};
that.on = function (type, method, parameters) {
// Register an event. Make a handler record. Put it
// in a handler array, making one if it doesn't yet
// exist for this type.
var handler = {
method: method,
parameters: parameters
};
if (registry.hasOwnProperty(type)) {
registry[type].push(handler);
} else {
registry[type] = [handler];
}
return this;
};
return that;
};
We could call eventuality on any inpidual object, bestowing it with event handling
We could also call it in a constructor function before that is returned:
eventuality(that)
In this way, a constructor could assemble objects from a set of parts. JavaScript’s
loose typing is a big benefit here because we are not burdened with a type system
that is concerned about the lineage of classes. Instead, we can focus on the character
of their contents.
If we wanted eventuality to have access to the object’s private state, we could pass it
the my bundle
我想大声告诉你2017-07-05 11:09:31
英文的 "parts" 意思是部分,这里我不知道该怎么准确的描述它的意思。大概就是说,可以通过一些方法将多个“部分”组合在对象上,在构建函数中,当然就是组合在 this
上。比如 eventuality
,简化一下
var eventuality = function(that) {
// 用于保存注册到 that 上的事件,闭包实现
var registry = {};
// 注册事件,将事件注册到 registry 中
that.on = function() {};
// 从 registry 中搜索对应的事情处理函数来执行
that.fire = function() {};
};
它会为传入的对象 that
添加 on()
和 fire()
两个方法用于事件的注册和触发,而闭包变量 registry
用于保存注册的事件(处理函数)。这个函数当然是为对象添加事件处理功能的。
假如我们还有一个其它功能需要添加到对象,比如序列化为 JSON,也就是添加一个 toJson()
方法将当前对象序列化成 JSON 字符串,比如
function jsonlity(that) {
that.toJson = function() {};
}
然后我们有一个 Boo
类,它除了自身的一些特性之外,还需要事件和 JSON 特性,那么在其构造函数中就可以这样
function Boo() {
// Boo 自身的构造内容
// ......
eventuality(this); // 添加事件功能
jsonlity(this); // 添加 JSON 支持
}
后面两句应该就是所谓的 compose parts 吧
这种方法会为每个对象设置相关方法函数的副本,不能重用定义的方法,所以还是比较耗资源的。不过教程中引入这一段应该是为了引出后面的继承这个知识点。
说到继承,ES2015 语法上已经支持 class 和 extends,比起之前的构造函数方式更加严格,也更方便,所以这部分我建议你多了解一下新的类语法,不要太纠结旧的类语法。以后有一定基础也有时间的时候,如果有兴趣,再去研究 JS 的原型机制和基于原型机制的 OO 实现。