15

The reason of using a

(0, foo.fn)();

is to cut the binding: the this will not longer be bound to foo but will be bound to the global object.

But what is the reason why any JavaScript code (or Google's JS code) would want to cut the binding? (and is it an anti-pattern or not?)

nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • calling it a *binding* doesn't feel right. `bind` method binds. Here it's just a context change. You can't cut or lose binding (the bond created by `bind`). – marzelin Dec 01 '19 at 11:26
  • maybe this code is generated by a transpiler from some functional language (clojurescript?) that has specific requirements when it comes to calling functions? – marzelin Dec 01 '19 at 11:37
  • 1
    possible duplicate of [Why does babel rewrite imported function call to (0, fn)(…)?](https://stackoverflow.com/q/32275135/1048572) - or where else are you seeing this? – Bergi Dec 01 '19 at 13:12
  • I think I saw it in Google's code and possibly in some framework like Angular, React, or some other ones... can't recall where and sometimes it is minified – nonopolarity Dec 01 '19 at 14:43

1 Answers1

13

This kind of code is typically generated by transpilers (like Babel), in order to convert modern JavaScript -- that uses the most recent additions to the specification -- to a JavaScript version that is more widely supported.

Here is an example where this transpilation pattern occurs:

Let's say we have this original code before transpilation:

import {myfunc} from "mymodule";
myfunc();

To make this ES5-compatible code, you could do this:

"use strict";    
var mymodule = require("mymodule");    
mymodule.myfunc();

But here we would execute myfunc with mymodule as this value, which is not happening in the original code. And although that might not always be an issue, it is better to make sure the function behaves just like it would in the original version, even if that function would use a this reference -- how unusual or even useless that use of this in myfunc might be (because also in the original version it would be undefined).

So for instance, if the original code would throw an error because of a this.memberFun() reference in the function, it will also throw in the transpiled version.

So that is were the comma operator is used to get rid of that difference:

(0, mymodule.myfunc)();

Granted, in code that you write yourself, you would never have a good use case for this pattern, as you would not use this in myfunc in the first place.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • How is `require` related to either ES6 or ES5? I used to think that require is a node module. – connexo Dec 01 '19 at 12:08
  • `require` is indeed a function available in node or else provided in libraries like browserify, require.js, ...etc. It is not specifically related to ES5/6. On the other hand, an ES6+ language construct like [`import`](https://www.ecma-international.org/ecma-262/6.0/#sec-imports) cannot be backported to ES5 without something like transpilation. – trincot Dec 01 '19 at 12:57
  • so if condensing it to several lines of a summary: if it is a library or module that includes a lot of functions that are not really methods or OO, (in the form of `modA.fn1`), then these functions really should not use `this` but if by accident they do, we don't want the `this` to affect the module in any way as a side effect, so we cut the binding, make it behave how it should behave if it is an independent function – nonopolarity Dec 01 '19 at 14:49
  • Yes, that is indeed how you could summarise it. Again, this is mostly a concern for transpilers, not so much of a coder. – trincot Dec 01 '19 at 15:42