Both classes and constructors can be used to create objects. The typeof
for both of them is function
. So, when should I use a class and when a constructor?

- 3,363
- 2
- 22
- 42

- 1,152
- 1
- 9
- 20
-
4There isn't really such a thing as a `class` in Javascript, classes are really just syntax sugar. You would use classes if you like how classes look & feel, you would use functional protototype if you like that. It's basically choice. – Keith Oct 18 '17 at 22:21
-
1@Keith yes there are now classes https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes – charlietfl Oct 18 '17 at 22:23
-
4@charlietfl You've not really understood what I've said.. note the `syntax sugar`, and is the reason why in both cases `typeof` returns `function`.. I've been using classes for a while now, I know the syntax exists, but it's just a fancy wrapper around normal functional prototype. – Keith Oct 18 '17 at 22:27
-
@Keith but taken the statement literally , and semantics aside, it is incorrect since there are classes. The fact they are wrappers isn't really relevant to the question and is more likely to confuse than help – charlietfl Oct 18 '17 at 22:30
-
3@charlietfl It's totally relevant, as the OP wanted to know why in both cases typeof returns function. I've now answered that question!!.. Do you have a better answer for why both return `function`? – Keith Oct 18 '17 at 22:32
2 Answers
A class is a constructor technically. Any object with a [[ Construct ]]
internal method is considered one. All constructors are functions, but not all functions are constructors.
Functions in Javascript can be of many kinds. We have normal functions, arrow functions, class, methods, async functions, async arrow functions, generators, async generators and possibly in the future generator arrow functions.
Out of all these functions, the only ones who can construct something are class
and normal functions. None other of these have a [[ Construct ]]
internal method.
There are some semantic differences between normal functions and classes as constructors and as callable functions:
- Only classes have
derived
constructors (which have a slightly different construction model). - Classes can't be called, only instantiated through
new
. - Classes have a
super
binding (which part of it is related to 1). - The prototype of the
class
(not theprototype
property) is the super constructor when there's anextends
clause. - The
prototype
property is not writable in classes, it is writable for normal functions.
Some other things that might be different from class
but can be done with normal functions:
class
code is strict mode by default.class
uses methods in their prototype. For normal functions as constructors they are typically also regular functions. This mean you can't construct new objects from class methods.class
methods in the prototype are not enumerable. For normal functions as constructors they are typically defined with=
and those make the properties enumerable.
Other relevant information:
- Classes are not instantiated until they reach the class declaration/expression. Top level function declarations are initialized right at the start of the function call and are accessible through out the whole scope.
constructor(){ }
inclass
is the only method definition that actually evaluates to a constructor. Methods are not constructors.

- 13,913
- 3
- 30
- 39
What @Keith said is quite true, and it is, for some odd reason, very hard for JS new-comers to grasp, consider this code:
Old School
With the old school way, things get syntactically messy:
function _Thing() {}
function _Person(name, age, from) {
this.name = name;
this.age = age;
this.from = from;
}
_Person.prototype = Object.create(_Thing.prototype);
_Person.prototype.constructor = _Person;//so easy to mess this up!
_Person.prototype.makeOlder = function () {
this.age++;
};
_Person.prototype.toString = function () {
return this.name;
};
_Person.FLORIDA = 1;
_Person.NEW_YORK = 2;
var _p = new _Person('rafael cepeda', 23, _Person.FLORIDA);
console.log(_p, _p instanceof _Person, _p instanceof _Thing);//_Person { name: 'rafael cepeda', age: 23, from: 1 } true true
New School
The ES6 way provides a very intuitive feeling for OOP programmers:
class Thing {}
class Person extends Thing {
constructor(name, age, from) {
super();
this.name = name;
this.age = age;
this.from = from;
}
makeOlder() {
this.age++;
}
toString() {
return this.name;
}
static get FLORIDA() { return 1; }
static get NEW_YORK() { return 2; }
}
var p = new Person('rafael cepeda', 23, Person.FLORIDA);
console.log(p, p instanceof Person, p instanceof Thing);//Person { name: 'rafael cepeda', age: 23, from: 1 } true true
Notice the parallels between the ES6 style constructor and the old school constructor, take a look at the prototype method definitions; with the new way, you don't even have to write the word prototype
(which scares js new-comers).
Because they are essentially the same thing, it is correctly coined syntactic sugar. After inspection of both constructors, it should be no surprise why both typeof
's return function
.

- 7,605
- 13
- 31
- 46
-
Your "old school" way doesn't work, you overwrite `Person.prototype` with a new object after having created all the methods. – Bergi Oct 19 '17 at 00:14
-
-
-
gah, you are correct, I guess that drives home my point, the extension is easy to mess up. I fixed it :) – Rafael Oct 19 '17 at 00:22