0

I saw this 'erroneous' calling of new keyword on Promise.resolve, but I am surprised that it works! Can someone please explain to me what is happening, and if it is different in any way to omitting the new keyword?

new Promise.resolve(1)

Looking at the MDN documentations for operator precedence (specifically Member Access, Function Call and new(without argument list)) and new keyword, shouldn't the above throw error, since I assume the expression is getting evaluated like such:

new (Promise.resolve(1))

I think I am missing something (obvious) here. Thanks in advance!

Note: Using bluebird library 2.x

jwgoh
  • 60
  • 7

2 Answers2

1

new is really just creating a new object and calls the given function with this set to that object. If Promise.resolve internally doesn't use this at all, then that makes no difference. Further, if the given constructor function returns an object itself, then the implicit object created by new gets discarded and the returned object is used instead.

So, new introduces a new intermediate object which gets discarded here since resolve returns a Promise, and it sets the context to a different object which doesn't seem to have any influence.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Doesn't seem to have any influence _except for extraneous memory consumption and decrease in performance due to unnecessary overhead, of course_. – Patrick Roberts Sep 25 '17 at 08:22
  • I mean *in functionality*. – deceze Sep 25 '17 at 08:24
  • It wasn't a criticism of your answer, more of an assurance to OP that "erroneous" shouldn't be in quotes, and that "it works" isn't a justification for accepting this practice. – Patrick Roberts Sep 25 '17 at 08:26
1

Here is a very good answer describing how the new operator works in JavaScript.

Essentially what is happening is that Promise.resolve is being treated as a constructor, however the constructed object is being discarded since Promise.resolve returns something (your promise object).

In this case, the new does no harm since Promise.resolve doesn't depend on access to this and, if you wish, it can simply be removed.

Conversely, adding new to an instance method invocation will result in very weird behaviour:

let x = Promise.resolve()
new x.then(() => console.log("Resolved")) // Will almost certainly throw an error
Benjamin Pannell
  • 3,645
  • 2
  • 19
  • 22
  • "Essentially what is happening is that Promise.resolve is being treated as a constructor" Do you mean that the expression above is being evaluated like such: `new (Promise.resolve)(1)`? – jwgoh Sep 25 '17 at 08:56
  • 1
    In JavaScript everything is, at its core, an object - so `new` doesn't know the difference between `new Promise()` and `new X()` (where `X = Promise.resolve`). So yes, while your brackets make the code look very odd, the evaluation order that they imply is correct. – Benjamin Pannell Sep 25 '17 at 20:16