If I have this basic structure
var Foo = function(str)
{
console.log('Object string: ' + this.str);
console.log('Param string : ' + str);
}
var Bar = function()
{
this.str = 'object string';
}
var obj = new Bar();
Foo.call(obj, 'param string');
It's fairly obvious what .call() is doing in context. I recently came across some articles that went into depth on abstracting the .call() function. The premise is along these lines (this code is verging on pseudo code as I have stripped it down for ease of reading) :
var Extension = {
// Fire a callback in global scope
fireCallback : function(event, args) {
this.callbacks[event].apply(window, args);
},
// Attach a callback
addCallback : function(event, fn) {
this.callbacks[event].push(fn);
},
// Now the bit that I really can't wrap my head around
enable : function() {
var self = this;
if ( ! self.callbacks ) {
self.callbacks = {};
}
self.fireCallback = function(event, args) {
Extension.fireCallback.call(self, event, args);
};
self.addCallback = function(event, fn) {
Extension.addCallback.call(self, event, fn);
};
}
}
There is some form of JS voodoo going on here that I can't programatically work out, can anyone help me shed light on how JS is interpreting this and why when I call:
Extension.enable.call(this);
within a class scope, the Extension object seems to extend the calling objects prototypes allowing me to bind a callback within the class scope. And then attach a handler after I have instantiated the class.
function Bar() {
Extension.enable.call(this);
// Do stuff
this.fnCallback = function()
{
this.fireEvent('complete');
}
}
var bar = new Bar();
bar.addCallback('complete', function(args)
{
console.log('complete');
});
bar.fnCallback(); // logs 'complete' to console
The logic is really confusing me, I understand how call() and apply() work in the simple example above but I have no idea how or why the prototypes of the object are extended when I call Extension.enable.call(this);
.
Could anyone help me shed some light on this?