Alternative to Function.bind

Erik Arvidsson erik.arvidsson at gmail.com
Thu Mar 26 23:01:07 PDT 2009


Here is one way to implement object.bind.method using ES3.1

Object.defineProperty(Object.prototype, 'bind', {
  enumerable: false,
  writable: false,
  configurable: false,
  get: function() {
    var rv = {};
    // this would need to use Object.getOwnPropertyNames and
    // recursively check Object.getPrototypeOf
    for (var key in this) {
      if (typeof this[key] == 'function') {
        rv[key] = this[key].bind(this);
      }
    }
    Object.freeze(rv);
    Object.seal(rv);
    Object.preventExtensions(rv);
    return rv;
  }
});

This does not create proxies for getters or setters nor values. It
does seal, freeze and prevent extensions on the bind proxy so that it
is clearer that it is not the object itself that you are operating on.
Another option is to replace all the "methods" on the object with the
bound methods.

Anyway, this is just an example of the power of the ES3.1 meta programming.

2009/3/26 Juriy Zaytsev <kangax at gmail.com>:
>
> On Mar 22, 2009, at 11:11 PM, Igor Bukanov wrote:
>
> Various current proposals for Function.bind have a drawback that in a
> typical situation one needs to use the reference to the object twice
> as in
>
>  obj.method.bind(obj)
>
> This double-referencing can be avoided if bind would be applied to the
> object, not to the function. The result of the bind call would be a
> view of the object that translates any function property of the object
> into a bound function so obj.method.bind(obj) could be written as
>
>  obj.bind().method
>
> Even shorter form can be archived if bind would not be a function but
> rather a getter-property so the above can be written as
>
>  obj.bind.method
>
> With such short form the need, for example, for Array methods taking
> an extra thisObj argument would be pretty much removed.
>
> This actually sounds like a great idea.
> As a matter of fact, implementing this in ES3 seems quite trivial:
> // Either with `Obejct.prototype.bind`
> Object.prototype.bind = function(methodName) {
>   var object = this;
>   return function(){
>     return object[methodName].apply(object, arguments);
>   }
> };
> var o = {
>   foo: function(){
>     return this.bar;
>   },
>   bar: 'Boo'
> };
> o.bind('foo')(); // "Boo"
> // or an alternative approach, which I like even more
> Function.bind = function(object, methodName) {
>   return function(){
>     return object[methodName].apply(object, arguments);
>   }
> };
> Function.bind(o, 'foo')(); // "Boo"
> --
> Juriy Zaytsev
> _______________________________________________
> Es-discuss mailing list
> Es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>



-- 
erik


More information about the Es-discuss mailing list