1

Is this implementation of JavaScript's Function.prototype.bind more or less correct?

Function.prototype.bindTemp = function () {

    const fn = this;
    var args = Array.prototype.slice.apply(arguments);
    const ctx = args[0];
    args = args.slice(1);

    return function () {
        return fn.apply(ctx, args.concat(Array.prototype.slice.apply(arguments)));
    }

};

anything obviously wrong or missing?

0

2 Answers 2

3

You've got the main idea, but if you look closely enough (at the spec) there are some points that are rather less correct:

  • bind should immediately throw a TypeError when not called upon a function
  • bind.length should be 1
  • the bound functions should not rely on the original to have an .apply method
  • the bound functions should not have a .prototype property
  • the bound functions should construct an instance of the same type as the original when invoked with new1
  • the bound functions should have the same prototype as the original2
  • the bound functions should have a .length that equals the arity of the original minus the number of bound arguments3
  • the bound functions should have a .name that contains the name of the original3

You'll find a better polyfill at MDN.

1: This cannot reliably distinguished prior to ES6. And to be pedantic, the bound functions should only be constructible at all if the original is as well.
2: This only became relevant as of ES6.
3: This can only be implemented with some kind of eval magic prior to ES6.

Sign up to request clarification or add additional context in comments.

Comments

1

As bind was not always cross browser, there was a polyfill for it, and it's mentioned in this question as well: Javascript's Bind implementation?

/*1*/       Function.prototype.bind = function ()
/*2*/       {
/*3*/           var fn = this,
/*4*/               args = Array.prototype.slice.call(arguments),
/*5*/               object = args.shift();
/*6*/           return function ()
/*7*/           {
/*8*/               return fn.apply(object,
/*9*/                   args.concat(Array.prototype.slice.call(arguments)));
/*10*/           };
/*11*/       };

The implementation (from John Resig's book) is the same as yours (nearly), so there shouldn't be anything wrong.

EDIT:

Returning a function created with () => instead of function() would avoid you storing the this variable into fn, as arrow functions bind the this above.

1 Comment

Just because a function was written by John Resig doesn't make it correct :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.