4

I'm trying to extend the functionality of a Promise and stumbled across this behaviour. I may be doing something silly but I'm confused.

Why does this code throw a SyntaxError?

Promise.constructor.call(this, function(){})
// Throws
// Uncaught SyntaxError: Unexpected token (
//   at Function (<anonymous>)
//   at <anonymous>:1:21

However this is fine

Promise.constructor.call(this, () => {})
Ally
  • 4,894
  • 8
  • 37
  • 45

2 Answers2

4

First, in order to make this clear, notice that Promse.constructor is just a reference to the Function constructor.

So basically you are just calling:

Function.call(this, function () {})

and:

Function.call(this, () => {})

The first expression throws because function () {} is not a valid function statement (but it's a valid function expression).

The problem is that being at the top block of the scope, the function identifier is matching the grammar of the statement form of the function declaration, and function statements should be named (that's why the error says ( is an "unexpected token", the parser it's expecting a name between the function keyword and the ( character).

If you do use a name, or use the comma operator, it will treat the function as an expression:

console.log(Function('0,function () {}'))

console.log(Function('function test() {}'))

With arrow functions there is no problem since they can only be expressions.

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • Thank you for the clear explanation. Learnt something new. – Ally May 21 '19 at 22:55
  • 1
    @Ally, you're welcome, if you want to go deeper in the differences between function statements vs expressions check: https://stackoverflow.com/questions/1634268/explain-the-encapsulated-anonymous-function-syntax/1634321#1634321 and https://kangax.github.io/nfe/ – Christian C. Salvadó May 22 '19 at 21:54
0

You cant create anonymous function like this either way, it's not promise constructor problem;

function(){}

Thrown: function(){} ^

SyntaxError: Unexpected token (