-3

MDN's polyfill for Function.prototype.bind (pasted below), uses the comma operator. Since the comma operator returns the last operand, and the first operand (oThis) doesn't do anything (like call a function, or make an assignment), it looks to be pointless. But I'm going to assume MDN knows what it's doing, so: What useful trick is the comma operator doing in this case?

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,  // <-- what's going on here?
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

To be clear, I'm suggesting that you could write fBound like this, and have it do the same thing:

        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : aArgs.concat(Array.prototype.slice.call(arguments)));
        };
Chris
  • 6,805
  • 3
  • 35
  • 50
  • 3
    This is within the call to `apply`, so this is just passing two parameters – _separated_ by a comma, as usual … – CBroe Aug 15 '14 at 02:20

2 Answers2

3

It is not a comma operator, it is a comma that separates the arguments of the function call to fToBind. You could rewrite as:

fBound = function () {
  var args = aArgs.concat(Array.prototype.slice.call(arguments));
  if (this instanceof fNOP && oThis) {
    return fToBind.apply(this, args)
  }
  return fToBind.apply(oThis, args)
};
elclanrs
  • 92,861
  • 21
  • 134
  • 171
1

It is equivalent to the following (except that the expressions assigned to arg1 and arg2 are evaluated prior to fToBind.apply, and the results are stored in variables):

var arg1 = this instanceof fNOP && oThis ? this : oThis;
var arg2 = aArgs.concat(Array.prototype.slice.call(arguments));
return fToBind.apply(arg1, arg2);

That is, the comma exists as an argument separator to the apply function call and is not parsed/realized as the comma operator.

user2864740
  • 60,010
  • 15
  • 145
  • 220