>说明:
- 使此代码正常工作,而无需以任何方式修改代码片段。
- 只使用普通的旧JavaScript,不要使用第三方库。
- 编写新代码,使以下代码能够正常工作。
提示:随意扩展本机对象...即使这通常是一种不好的做法。
// Start with an object, any object
var myObject = {};
// Register an event on your object using
// an `on` method
myObject.on('myEvent', function(data) {
// Log the data passed to the callback
console.log(data);
});
// Trigger the event using a `trigger` method.
// Include some data when you trigger the event.
myObject.trigger('myEvent', {
company: 'ABC Corp',
location: 'WTC Bangalore, IN',
website: 'http://abc.co'
});
// Register a different event
myObject.on('yourEvent', function() {
console.log('yourEvent fired');
});
// Trigger the new event
myObject.trigger('yourEvent');
// Trigger all existing events using a special
// "star" identifier.
myObject.trigger('*');
// Remove one event by name
myObject.off('myEvent');
// Since we've removed the event, this should
// do nothing
myObject.trigger('myEvent');
// Remove all existing events
myObject.off();
// Since we've removed all events, this should
// do nothing
myObject.trigger('*');
其他一切都很顺利。我在实现myObject.trigger("*")
时无法获得"参数";在实现"*"
时无法读取参数对象/参数,因此抛出undefined
。
My JSFiddle
免责声明我显然不知道你上什么学校或什么,但请不要欺骗自己试图愚弄你的老师。通过几个简单的问题,他们就会知道你是否理解材料,如果你出现一个很好的答案但没有知识来支持它,他们就会知道发生了什么。我不是在指责你,只是对去年毕业后与老师有良好关系的人的友好建议;)
那么,我们如何做到这一点呢?基本上,您必须添加一些功能 object
原型 ,至少如果您希望这影响之后制作的所有对象。如果您只希望该类具有此功能,则始终可以创建自己的类并将函数添加到该原型中。
我们需要在原型中添加 3 个功能,on
,当然是off
和trigger
。最重要的是,我们添加了一个名为 events
,最初是一个空对象。您可以在 jsfiddle 中查看所有这些的原始代码,我在这里只介绍代码的结构和逻辑。
events
将保存与每个事件关联的所有处理程序(函数(。第一次添加事件时,我们向events
对象添加一个 eventName
属性,此属性的值最初是一个空数组。
on
将在 events
中找到(或创建(链接到eventName
的数组,并将函数推送到数组中(注意我们此时不调用函数,我们只是将对函数的引用存储在数组中(。
off
将迭代eventName
数组,如果它找到相同的函数(注意===
(,则将其从数组中删除。
trigger
将迭代eventName
数组并调用每个函数。请注意,该函数是使用设置为对象的函数中的 this
关键字调用的,并且使用与调用trigger
函数相同的参数(第一个参数 eventName 除外,它被过滤掉(。是的,这意味着您可以传递任意数量的参数 trigger((,并且它们都将传递给每个处理程序。
我不会详细介绍像splice
,slice
,===
,arguments
和apply
之类的事情,我相信你可以在万维网的其他地方找到更多更好的信息。
为此,您可以做更多的事情,例如通过一些很好的范围使用使events
对象不可见,但这不是问题的一部分,所以我没有为此烦恼。
如果您在阅读本文后还有其他问题,请随时提问。我也没有对其进行广泛的测试,所以如果您发现任何错误,请告诉我。
编辑:起初我没有通读评论,但现在我还添加了对"*"通配符的支持。基本上,函数现在检查通配符,并在删除或触发时迭代event
对象上的所有eventName
。您还可以通过不给出函数或提供相同的通配符但使用 eventName 来删除事件的所有函数。
EDIT2:运行老师的代码时有一些错误,意识到我在迭代时忘记检查hasOwnProperty
。看看那个,在使用原型时非常重要!我现在在我的jsfiddle中输入了老师的代码,以向您展示它的工作原理:)
JSFIDDLE 与自己的代码
JSFIDDLE 与教师代码
编辑3 - 关于"未定义"日志。
老师的代码调用.trigger
5 次,您应该会看到 4 个控制台日志,据我所知,它们都是正确的。让我运行每个触发器和后续控制台日志。
- 将处理程序添加到
myEvent
,该处理程序记录第一个参数 - 触发
myEvent
,参数 => 参数(对象(为登录。 - 将处理程序添加到
yourEvent
,这将记录硬编码字符串。 - 你触发
yourEvent
,没有参数=>记录硬编码的字符串' - 您触发
*
没有参数,所有处理程序运行 => 未定义被记录,因为没有给出参数,data
myEvent
的处理程序是未定义的。还会记录硬编码字符串 - 删除
myEvent
处理程序,触发myEvent
并确认未调用任何函数 - 删除所有事件处理程序,触发
*
并确认没有从任何事件调用任何函数。
老实说,我不知道您希望在步骤5上发生什么,因为您没有给出参数,data
被分配undefined
,这是预期的行为。
如果要合并步骤 2 中给出的数据,使其保留在对象上,请在处理程序中指示。(例如,迭代data
的所有属性并将它们添加到 this
,然后记录this
(。现在你只需传递它数据,它就会被记录下来,然后扔掉。您还可以在步骤 5 中添加参数,然后所有处理程序都将收到它(包括yourEvent
处理程序,但该处理程序不会分配或使用它(。
document.getElementById("myBtn").addEventListener("click", displayDate);