Just a humble attempt to propose some addiction to the `Object.prototype` I
already know many will kill me for even trying to ...

**tl;dr** - everything proposed can be already tested through this utility
called [eddy.js](https://github.com/WebReflection/eddy#event-driven-js)

### Event Target All The Things
One of the most widely adopted API in JavaScript world is based on a
combination of these methods:

 * `.on(type, handler[, capture])` used as equivalent of `addEventListener`
in the DOM namespace, also used in every library that would like to be
event driven. Smart enough to avoid duplicated entries for the same handler
over the same event type.
 * `.once(type, handler[, capture])` used to simplify `.on()` within an
`.off()` at the top of the invocation to ensure a "one shot only" event
 * `.off(type, handler[, capture])` to remove a previously set event
handler or silently failif not present
 * `.emit(type[, arg1][, argN])` directly from node.js world where almost
every object is an EventTarget and EventEmitter anyhow since it's needed
and has been proven it's a highly appreciated/welcome approach.
 * `.trigger(type[, data])` similar to `.emit()` except it triggers/fires
an event object with some extra method such
`evt.stopImmediatePropagation()` or others DOM related when the event comes
from DOM

The proposed implementation lazily assign internal listeners event handlers
only once these methods are invoked for the very first time.

This makes every object able to be promoted at runtime as event emitter:
```javascript
var o = {};
// o is just an object

o.on('event-name', console.log.bind(console));
// now o has internals able to work with handlers

o.trigger('event-name');
// will log an Event object
```

### An Extra "Should Have" Utility
We talk a lot about GC these days and performance impact this has on slower
device (or embedded ARM boards such R-PI or Cubieboard, hardware used in
production and as server too in some crazy case!).

There is a common **anti pattern** in JS code since some library introduced
`Function#bind()` and ES decided to adopt it: it creates N new objects per
each call.

This makes it impossible to remove listeners so we are forced to address
every single object. As example, back to a similar previous code example:
```javascript
window.addEventListener('load', console.log.bind(console));
// now how to drop that ?
```
There is no way to remove that listener after that and developers keep
passing functions, instead of objects with `handleEvent()` methods, and
more complex code becomes easily messed up.

`Object.prototype.boundTo(method)` would be able to solve this in a very
simple way: creates, if not created already, a bound version of that method
so that any further call to the same method will result in the same bound
object.

```javascript
window.addEventListener('load', console.boundTo(console.log));

// whenever we want to ...
window.removeEventListener('load', console.boundTo(console.log));
```
In my `eddy.js` proposal this method has a shortcut too, shortcut that
might break if some obtrusive minifier as Closure Compiler with ADVANCED
option is taking care of the build process. This is why I am not expecting
much consensus about the overload of this `boundTo()` method but here what
I've done:
```javascript
window.addEventListener('load', console.boundTo('log'));

// whenever we want to ...
window.removeEventListener('load', console.boundTo('log'));
// same as
window.removeEventListener('load', console.boundTo(console.log));
```
The method can accept either a function or a string, where in latter case,
the `context[methodName]` is used to check if the bound object has been
created already.

`.boundTo(method)` should not accept extra arguments since in that case
advantages are less than a generic bind due very exponential nature of the
possible check over all arguments. In that case developers can use bind and
address it if really needed but I've seen this is not the majority of the
cases.


**Thank You** for listening, reading, sharing thoughts, or proposing any
change ... I know I'm going to be probably the only one in this planet that
will pollute in a non enumerable way the `Object.prototype` with the stuff
I need the most in every single piece of JS software I've written but hey
... maybe it was worth it to try to propose here too :-)

Best Regards
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to