Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Created January 6, 2012 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save WebReflection/1569978 to your computer and use it in GitHub Desktop.
Save WebReflection/1569978 to your computer and use it in GitHub Desktop.
proposal to bind once object as callback context pairs
!function (Object) {
// (C) WebReflection - Mit Style License
var // private scope shortcuts
BOUND_TO = "boundTo", // or maybe "asContextOf" ?
// ad-hoc partial private shims for "not there yet" ES5 browsers
indexOf = [].indexOf || function indexOf(value) {
for (var i = this.length; i-- && this[i] !== value;);
return i;
},
bind = indexOf.bind || function bind(self) {
var callback = this;
return function bound() {
return callback.apply(self, arguments);
};
},
defineProperty = Object.defineProperty
;
// feature detect defineProperty (IE8 inconsistency)
try {
if (!defineProperty({},"_",{value:1})._) {
throw 1;
}
} catch (o_O) {
// in IE8 it will be enumerable, configurable, writable
defineProperty = function defineProperty(
object, key, descriptor
) {
object[key] = descriptor.value;
};
}
// avoid double assignment
if (BOUND_TO in Object.prototype) return;
defineProperty(
Object.prototype,
BOUND_TO, {
value: function (callback, remove) {
// only the very first time
// two private stacks are created
// and related to the current object
// WeakMap behavior emulated
var
cbStack = [],
boundStack = [],
self = this
;
// overwrite the inherited BOUND_TO method
// with the one we actually need
defineProperty(
self,
BOUND_TO, {
value: function boundTo(callback, remove) {
var
i = indexOf.call(cbStack, callback),
callback = i < 0 ?
boundStack[
i = cbStack.push(callback) - 1
] = bind.call(callback, self)
:
boundStack[i]
;
// falsy values accepted
// except null or undefined
// so it's true by default
if (remove == false) {
cbStack.splice(i, 1);
boundStack.splice(i, 1);
}
// returns bound callback in any case
// handy to remove listeners and clean stacks
// in one single operation
return callback;
}
}
);
// only the first time, invoe the overwritten method
// use directly latter one every other time
return self[BOUND_TO](callback, remove);
}
}
);
}(Object);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment