This question already has answers here:
Closed 3 years ago.
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.
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.
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:
- A new object is created, inheriting from Foo.prototype.
- 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.
- 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.