如何解决道格拉斯·克罗克福德Douglas Crockford的“ Javascript:好的部分”第5.5章
| 我正在阅读本书标题的第5.5章。使用本章中的事件功能,如何查看“我们可以用零件组构成对象”仍然很麻烦。 对象是否由具有“ on”和“ fire”功能的事件系统组成? 以下部分的代码: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;
}
解决方法
Crockford先生在这里的意思是,您可以实现特定的功能,例如
on
和fire
函数,这些函数通过调用以对象为参数创建对象的函数对象(本例中为eventuality
)来向任何对象添加事件处理。
这里的“部分”是体现在“ 3”功能对象中的“事件处理部分”。您可以想象添加其他功能的不同部分。这里的想法是,您可以使用该系统将该功能添加到需要的单个对象中。这个概念称为Mixin(1)。
另请阅读第5章的最后一段:
这样,构造函数可以从一组零件中组装对象。 JavaScript的松散类型在这里是一个很大的好处,因为我们不必为担心类沿袭的类型系统感到负担。
(1)谢谢Zecc。
, 据我了解,本书本节的重点是说明JavaScript的功能-您可以轻松地使用所有各种“强大的JavaScript组件”构建对象。
正如他所说
例如,我们可以做一个函数
可以添加简单的事件处理
任何对象的特征。它增加了一个
方法,射击方法和私人
事件注册表
, 任何一种方式都是可能的。我是作者的忠实粉丝,他对我来说就像个英雄。无论如何,javascript为我们提供的最佳功能之一就是动态对象。我们可以根据需要创建对象。
, 以下是我自己的测试结果。如果复制代码并将其粘贴到名为“ test.js”的文件中,然后在命令行上通过“ node test.js”(必须已经安装了节点)运行它,则将获得相同的结果。我的工作是向您展示如何通过带有不言自明的注释来跟踪eventuality()。
我唯一不了解的地方是直线; \“ fund = this [func] \”(以\“ ??? \”作为注释)。 “ \ func = Registry [func] \”对我来说似乎更有意义,因为注册表对象是处理程序的注册位置,而不是最终功能对象(即\'this \')。
var eventuality = function(that) {
var registry = {};
that.fire = function(event) {
var type = typeof event === \'string\' ? event : event.type;
console.log(\'fire(): fired on event,\"\' + type + \'\"\');
if (registry.hasOwnProperty(type)) {
var array = registry[type];
for (var i = 0; i < array.length; ++i) {
var handler = array[i];
console.log(\'fire(): handler found at loop \' + i);
var func = handler.method;
var pars = handler.parameters;
if (typeof func === \'string\') {
console.log(\'fire(): the found func is a string\');
func = this[func]; // ???
} else {
// Invoke the handler with parameters.
console.log(\'fire(): the found method is NOT a string\');
func.apply(this,[pars]);
}
}
}
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)) {
// If already registered:
registry[type].push(handler);
} else {
// If it\'s first time:
console.log(\'on(): \"\' + type + \'\" event registered\');
registry[type] = [handler];
}
return this;
}
return that;
};
var dog_is_hungry = {
type: \'is_hungry\'
};
var dog_needs_to_poo = {
type: \'needs_to_poo\'
};
var dog_methods = {
feed: function() {
console.log(\'Event processed by the handler,dog_methods.feed(): \');
for (var i = 0; i < arguments.length; ++i) {
console.log(\' Feed the dog with the \"\' + arguments[i].food + \'\"\');
}
},walk: function() {
console.log(\'Event processed by the handler,dog_methods.walk(): \');
for (var i = 0; i < arguments.length; ++i) {
console.log(\' Walk the dog to the \"\' + arguments[i].place + \'\"\');
}
}
};
var myDog = {
name: \'Lucky\',age: 2
}
var myDogEHM = eventuality(myDog); // EHM - events handling manager
console.log(\'My dog is named \' + myDogEHM.name);
console.log(\'My dog is aged \' + myDogEHM.age);
// Register the event-handlers
myDogEHM.on(dog_is_hungry.type,dog_methods.feed,{
food: \'rice and meat\'
});
myDogEHM.on(dog_needs_to_poo.type,dog_methods.walk,{
place: \'park\'
});
// Events to be handled
myDogEHM.fire(dog_is_hungry);
myDogEHM.fire(dog_needs_to_poo);
, 我进一步修改了Daniel C Deng的示例,以进一步解释this [func]的用法。此代码在Chrome的JavaScript控制台中运行。
var eventuality = function(that) {
var registry = {};
that.fire = function(event) {
var type = typeof event === \'string\' ? event : event.type;
console.log(\'fire(): fired on event,\"\' + type + \'\"\');
if (registry.hasOwnProperty(type)) {
var array = registry[type];
for (var i = 0; i < array.length; ++i) {
var handler = array[i];
console.log(\'fire(): handler found at loop \' + i);
var func = handler.method;
var pars = handler.parameters;
if (typeof func === \'string\') {
console.log(\'fire(): the found func is a string\');
func = dog_methods_2[func];
//javascript turn string into object reference.
//https://stackoverflow.com/questions/10953303/javascript-interpret-string-as-object-reference
}
// Invoke the handler with parameters.
//console.log(\'fire(): the found method is NOT a string\');
func.apply(this,[pars]);
}
}
return this;
};
that.on = function(type,parameters: parameters
};
if (registry.hasOwnProperty(type)) {
// If already registered:
registry[type].push(handler);
} else {
// If it\'s first time:
console.log(\'on(): \"\' + type + \'\" event registered\');
registry[type] = [handler];
}
return this;
}
return that;
};
var dog_is_hungry = {
type: \'is_hungry\'
};
var dog_needs_to_poo = {
type: \'needs_to_poo\'
};
var dog_is_thirsty = {
type: \'needs_to_drink\'
};
var dog_methods = {
feed: function() {
console.log(\'Event processed by the handler,dog_methods.walk(): \');
for (var i = 0; i < arguments.length; ++i) {
console.log(\' Walk the dog to the \"\' + arguments[i].place + \'\"\');
}
},strings: [\"drink\"]
};
var dog_methods_2 = {
drink: function() {
console.log(\" The dog drinks \" + arguments[0].drink + \".\");
}
}
var myDog = {
name: \'Lucky\',{
place: \'park\'
});
// Events to be handled
myDogEHM.fire(dog_is_hungry);
myDogEHM.fire(dog_needs_to_poo);
myDogEHM.on(dog_is_thirsty.type,dog_methods.strings[0],{
drink: \'water\'
});
myDogEHM.fire(dog_is_thirsty);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。