Reputation: 444
Instructions:
Hint: Feel free to extend native objects... even though it's typically a bad practice.
// 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('*');
Everything else went well. I'm unable to get "arguments" while implementing myObject.trigger("*")
; unable to read arguments object / parameters while implementing "*"
and hence throw undefined
.
Upvotes: 2
Views: 1519
Reputation: 558
Disclaimer I obviously dont know what school you go to or anything, but please don't fool yourself trying to fool your teachers. With a few simple questions they'll know if you understand the material or not, and if you show up with a good answer but no knowledge to back it up, they will know what's up. I'm not accusing you of this, just a friendly word of advice of someone who has had good connections with his teachers after graduating last year ;)
So, how do we do this? Basically, you will have to add some functionality to the prototype of object
, at least if you want this to affect all objects made afterwards. You can always create your own class and add the function to that prototype if you only want that class to have this functionality.
We need 3 functions added to the prototype, on
, off
and trigger
of course. On top of that we add one extra property called events
, initially an empty object.
You can look at the raw code for all these in the jsfiddle, I will only go through the structure and logic of the code here.
events
will hold all the handlers (functions) associated with each event. When adding an event for the first time, we add a eventName
property to the events
object, the value for this property is initially an empty array.
on
will find (or create) the array linked to eventName
in events
, and push the function into the array (note we do not call the function at this time, we simply store the reference to the function in the array).
off
will iterate the array of eventName
, and if it finds the same function (note the ===
), remove it from the array.
trigger
will iterate the array of eventName
and call each function. Note that the function is called with the this
keyword in the function set to the object, and with the same parameters as the trigger
function was called (except eventName, the first parameter, which is filtered out). Yes that means you can pass as many parameters as you want to trigger(), and they will all be passed to each handler.
I won't go into detail what things like splice
, slice
, ===
, arguments
and apply
do exactly, I'm sure you can find more and better information about that elsewhere on the world wide interwebs.
There's a lot more you can do for this, like making the events
object invisible through some nice uses of scoping, but that wasn't part of the question so I didn't bother with that.
If you have any more questions after looking through this, feel free to ask. I also didn't test it extensively so if you find any bugs, let me know.
EDIT: I didn't read through the comments at first, but I now also added support for the '*' wildcard. Basically the functions now check for the wildcard and will iterate all eventName
s on the event
object when removing or triggering. You can also remove all functions for an event by not giving a function or by giving the same wildcard, but with an eventName.
EDIT2: had some bugs running the teacher's code, realized I forgot to check for hasOwnProperty
while iterating. Look that one up, it's very important when working with prototypes!
I now put in the teacher's code in my jsfiddle, to show you that it works :)
EDIT3 - about the 'undefined' log.
The teacher's code calls .trigger
5 times, and you should see 4 console logs and as far as I can tell, they are all correct.Let me run through each trigger, and the subsequent console logs.
myEvent
, which logs the first parameter myEvent
, with parameter => The parameter (the object), is
logged. yourEvent
, which logs a hardcoded
string.yourEvent
, no parameter => The hardcoded string is logged'*
with no parameter, all handlers run => undefined is logged, since no parameters were given, data
in myEvent
's handler is undefined. The hardcoded string is also loggedmyEvent
handler, trigger myEvent
and confirm no functions are called*
and confirm no functions are called from any events.I honestly don't know what you expected to happen on step 5, since you give no parameter, the data
is assigned undefined
, that's intended behaviour.
If you want to merge the data given in step 2 so it remains on the object, then instruct so in your handler. (for example, iterate all properties of data
and add them to this
, then log this
). Right now you simply pass it data, it gets logged, and then thrown away. You can also add a parameter in step 5, and then all handlers will receive it (including the yourEvent
handlers, but that one doesn't assign nor use it).
Upvotes: 3
Reputation: 363
document.getElementById("myBtn").addEventListener("click", displayDate);
Upvotes: 0