Sometimes, you need to pass a callback as a parameter of a function.

Sometimes, you would like to pass in a method as the said parameter but you may encounter the common issue that the this keyword is not bound to the correct context anymore ; therefore you need to bind the correct context.


Let's says that you have :

  • a function `f` which receives a callback
  • and an object `obj` which has a method `method` which requires the `this` keyword to be bound to `obj` in order to work properly as intended.


You will probably call `f` this way :



This is perfectly fine but sometimes can lead to a very large amount of extra "effort" for something that should not require that much "effort" and tends to take away a lot of space and clarity :`



My suggestion to solve this issue would be to use a new notation based around what C++ developers call the scope resolution operator, aka `::`.

Here are details on how this should work :

  • `{object}` refers to an object (it can be either obj, or obj.method, or obj.prop, etc...)

  • `{method}` refers to one of `{object}`'s methods (if `{object}` is obj and we have `obj.method` then `{method}` would be `method`)

  • The "old-fashioned" way would look like `{object}.{method}.bind({object})`

  • With this suggestion, it would look like `{object}::{method}`


One way to implement such a functionality would be to establish a function autoBindContext which would guarantee the following properties :

  • `{object}::{method}` <=> `autoBindContext({object}.{method}, {object})`

  • Given any function/method `{fn}` (either `f` or `obj.method`), `autoBindContext({fn}, null) === {fn}`

  • `{object}::{method}` <=> `({object})::{method}`

  • const a = {object}::{method}; 
    const b = {object}::{method}; 
    a==b; //is true 
    a===b; //is true 


Below is one implementation of autoBindContext :


const autoBindContext = (method, context=null) => {
  if(typeof method !== "function")
    throw new TypeError("Can only bind the context of a function/method");
  if(context === null)
    return method; //Do not bind if the context is null
  if(!(context instanceof Object))
    throw new TypeError("Can only bind a function's/method's context to an object");
  const self = autoBindContext;
  if(!self.cache.hasBinding(method, context))
    self.cache.addBinding(method, context);
  return self.cache.getBinding(method, context);
autoBindContext.cache = {
    binding: {context, method, bound}
    bindings: [],
  lookForBinding(method, context=null){
    return this.bindings.find(binding => {
      return binding.context === context
      && binding.method === method;
  hasBinding(method, context=null){
    return this.lookForBinding(method, context) !== undefined;
  getBound(method, context=null){
    if(this.hasBinding(method, context))
        return this.lookForBinding(method, context).bound;
    return null;
  getBinding(method, context=null){
    return this.getBound(method, context);
  addBinding(method, context=null){
    if(!this.hasBinding(method, context)){
        bound: method.bind(context)
    return this;


es-discuss mailing list

Reply via email to