33

What is it about Javascript that lets me use inverted / backwards parentheses in function calls like this? I'm running in a Node console on the CLI; specifically Node version 0.10.25.

function a(){ return 42 }
a() // -> 42
a)( // -> 42.  WTF?

function b(t){ return t }
b(4) // -> 4
b)4( // No function evaluation; presumably dangling parentheses
b)(4 // -> 4.  WTF?

Addendum: This doesn't appear to work in Chrome 33.0.1750.152, Safari 7.0.2, or Firefox 27.01. Is this actually some kind of "feature" of some interpretation of ECMAScript, or a Node peculiarity? If Node is using V8, shouldn't it match up with the Chrome results?

Bryce
  • 2,157
  • 17
  • 16

1 Answers1

23

It is possible that the console wraps everything inside an eval statement: what is actually evaluated is maybe eval(a)(). In that case Chrome returns 42 as well.

fabiolune
  • 321
  • 2
  • 8
  • 1
    Or even just a set of parentheses: `a)(` => `(a)()` – Cᴏʀʏ Mar 20 '14 at 17:20
  • 2
    Alright now who's going to look inside all the node.js source code to verify that? – Romain Braun Mar 20 '14 at 17:21
  • 1
    +1 This is definitely the case. If you read here in the docs, you'll see that each line is evaluated using eval: http://nodejs.org/api/repl.html `eval - function that will be used to eval each given line. Defaults to an async wrapper for eval()` – Matthew Blancarte Mar 20 '14 at 17:24
  • 7
    Guessing this is the line right here: `evalCmd = '(' + evalCmd + ')\n';` https://github.com/joyent/node/blob/master/lib/repl.js#L268 – cookie monster Mar 20 '14 at 17:28
  • I'm surprised the eval doesn't consider the line as a string. In that case, `eval("a)(")` results in the same trailing-parens non-evaluation. – Bryce Mar 20 '14 at 17:28
  • 1
    Based on what @cookiemonster found, it's evaluating as `eval('(a)()')` – Matthew Blancarte Mar 20 '14 at 17:33
  • 1
    @MatthewBlancarte: The cause isn't so much that it's in an `eval` call, but more specifically that the code is wrapped in `"("` and `")"` before being `eval`'d. – cookie monster Mar 20 '14 at 17:33
  • 1
    @cookiemonster For sure. I was just commenting that it was, indeed, using `eval` Good find there in `repl.js` which totally clears up what's going on. – Matthew Blancarte Mar 20 '14 at 17:36
  • 1
    @MatthewBlancarte: Sure, just that the answer isn't quite right the way it reads. I'm not even sure that it's actually `eval` that's used, otherwise the code would be able to access the internal local variables. Probably uses the `Function` constructor, or something else. Or maybe it sends it to a safe scope before evaluation. But that's beside the point. We can think of it as `eval` either way. – cookie monster Mar 20 '14 at 17:40
  • Likewise, defining function a () { return function () { return 2; } } causes 'a)()(a' to return 2 – waTeim Mar 20 '14 at 18:13