11

As far as I know, arrow function is similar to normal function. There is no problem when I use like this:

let X = () => {};
let Y = function() {};
X();
Y();

However, error occurred when I use them with new

let X = () => {};
let Y = function() {};
x = new X();
y = new Y();

Uncaught TypeError: X is not a constructor

Would you please explain me why? Many thanks.

Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
Ricky
  • 369
  • 2
  • 16
  • The error itself gives you an answer.... you defined X to be an empty object, not a constructor method/function, as such you cannot invoke it with the "new X();" expression. – Dellirium Jun 02 '16 at 09:41
  • hmm, I see. But I wonder why `new Y()` does not cause error. Maybe JS do some magic things with function, not arrow function ? – Ricky Jun 02 '16 at 09:45
  • Two possibilities: 1. ) Because your Y is a function, an empty one at that, though still defined as a function. 2) Because the code breaks and y = new Y(); is never run. You cannot get the object returned from the arrow functions as they give you now "this" to return – Dellirium Jun 02 '16 at 09:47
  • Because you can't as the documentation says. –  Jun 02 '16 at 09:47
  • 1
    [link](http://stackoverflow.com/questions/22939130/when-should-i-use-arrow-functions-in-ecmascript-6) may help you – The Reason Jun 02 '16 at 09:48
  • 2
    See also http://stackoverflow.com/questions/34361379/arrow-function-vs-function-declaration-expressions-are-they-equivalent-exch. –  Jun 02 '16 at 09:49
  • @torazaburo That's a better duplicate target. – 1983 Jun 02 '16 at 10:05
  • @torazaburo both questions you provided are rather canonical and don't answer the specific question of the OP in my view – scriptum Jun 02 '16 at 10:12
  • @Iven Well, it's a canonical question. If you disagree with closing it against those dups, then vote to re-open. Both questions seem to quite clearly indicate that arrow functions are not constructors. –  Jun 02 '16 at 10:14
  • Arrow functions cannot be used as constructors as stated in the docs [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) – Tahir Raza Nov 05 '18 at 05:11

2 Answers2

17

You may wish to clarify your question.

Q. What did I do wrong?

A. You used new with an arrow function, and that's not allowed.

Q. Can I turn an arrow function into a constructor?

A. Only by wrapping it in a normal function, which would be silly. You can't turn an arrow function itself into a constructor.

Q. Can you explain how the specification disallows new with arrow functions?

A. To be a constructor, a function object must have a [[Construct]] internal method.

Functions created with the function keyword are constructors, as are some built-in functions such as Date. These are the functions you can use with new.

Other function objects do not have a [[Construct]] internal method. These include arrow functions. So you can't use new with these. This makes sense since you can't set the this value of an arrow function.

Some built-in functions are also not constructors. E.g. you can't do new parseInt().

Q. Can you explain the rationale behind disallowing new with arrow functions in the specification?

A. Use common sense, or search the es-discuss archives.

1983
  • 5,322
  • 1
  • 24
  • 38
  • 1
    @Ricky I deleted my answer, because [`new` doesn't depend on the constructor's prototype](http://www.ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor). Since you can't set `this` of arrows with `apply` or `bind`, it is consistent behavior to prohibit the application of `new` too. This is the best answer. – scriptum Jun 02 '16 at 10:54
3

Arrow functions are not synonymous with normal functions. arguments and this inside arrow functions reference their outer function.

When the code new Foo(...) is executed, the following things happen:

  1. A new object is created, inheriting from Foo.prototype.
  2. The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
  3. The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

Since this inside an arrow function references its outer function (arrow functions inherit this from their declaration context, as @Iven is saying), using new keyword with an arrow function does not really make sense.

Bugs Bunny
  • 1,992
  • 1
  • 23
  • 27
  • I have just read about it. But still don't understand why I can not create object like that – Ricky Jun 02 '16 at 09:46
  • This answer has nothing to do with the question, which is why arrow functions do not function as constructors. –  Jun 02 '16 at 09:48
  • 2
    It is not that using `new` keyword with an arrow function "does not make sense". It is **illegal**. –  Jun 02 '16 at 10:13