Function.prototype.bind (was: Topic list - pending changes and issues for the ES3.1 spec)

Garrett Smith dhtmlkitchen at
Tue Sep 9 19:58:00 PDT 2008

On Tue, Sep 9, 2008 at 10:39 AM, Mark S. Miller <erights at> wrote:
> On Tue, Sep 9, 2008 at 9:21 AM, Mark S. Miller <erights at> wrote:
>> I still need to spec Function.prototype.bind in our funny spec language.
>>    Anyone care to contribute a draft?

> The simplest way to specify this would be in terms of the rest of the
> ES3.1 spec, i.e., a "self-hosting" spec. Perhaps like the following:

So self-hosting is where new features are written using EcmaScript
while the real implementation could be written in another language,
like C++?

This would be useful for testing. It would provide a common and
reliable reference, for example:-

if(!Function.prototype.bind) {
 Function.prototype.bind = function(context) {
 /** From EcmaScript H */

In your example:-

>  Function.prototype.bind = function(self, var_args) {
>    var thisFunc = this;
>    var leftArgs = Array.slice(arguments, 1);
>    return function(var_args) {
>      var args = leftArgs.concat(Array.slice(arguments, 0));
>      return thisFunc.apply(self, args);
>    };
>  };

what are the two var_args parameter variables for? They are never used.

I prefer the variable name 'context' over 'self', to be more
consistent with the current spec, so:-

 * @param {Object} context - the "this" value to be used.
 * @param {arguments} [1..n] optional arguments that are prepended
 * to returned function's call.
 * @return {Function} a function that applies the original
 * function with - context - as the thisArg.
Function.prototype.bind = function(context) {
   var thisFunc = this,
         leftArgs = Array.slice(arguments, 1);
   return function() {
     var args = leftArgs.concat(Array.slice(arguments, 0));
     return thisFunc.apply(context, args);

But that would not be the most efficient way. This 'bind' method does
bind + partialApply. There are currently bind methods that do only
bind (and not partial apply)[JSAN]. It is simpler and more efficient,
when that's all you need.

However, if the requirement for bind is to perform bind +
partialApply, we could have our bind() return a function that does
either bind or bind + partialApply.

function GarrettsBind(context){
  var fn = this,
      slice = Array.prototype.slice,
      isPartial = arguments.length > 1;
        args =, 1);

  // Strategy 1: just bind, not a partialApply
  if(!isPartial) {
    return function() {
      if(arguments.length !== 0) {
        return fn.apply(context, arguments);
      } else {
        return; // faster in Firefox.
  } else {
  // Strategy 2: partialApply
    return function() {
        return fn.apply(context,
         arguments.length===0 ? args:args.concat(;

Pure bind would keep things simple:

Function.prototype.bind = function(context) {
  return function() {
    if(arguments.length !== 0) {
        return fn.apply(context, arguments);
      } else {
        return; // faster in Firefox.

(Function.prototype.apply should be optimized when or arguments[1] is
undefined or its "length" is 0.)


> Post ES3.1, we hope to turn in general to the specification style that
> had been used for the ES4 spec -- SML + self-hosting. However, even
> the ES3 spec does make some use of self-hosting language such as "as
> if by the expression 'new Object()'", which the ES3.1 draft keeps, but
> clarifies to refer to the original binding of 'Object'. Could we use
> the same trick for Function.prototype.bind by saying something like
> "the original bindings of Array.slice, Array.prototype.concat, and
> Function.prototype.apply? Post ES3.1, to enable self-hosting specs,
> we'll need to solve this problem anyway. Any ideas how we should do
> that then?
Self-hosting new/complicated things sounds like a useful idea. It
clarify what the code does, make it testable, and provide useful code
for developers to fall back on (for implementations that don't yet
support the new feature).

> --
>    Cheers,
>    --MarkM

More information about the Es-discuss mailing list