Are these interchangeable syntax\'s to create a JS class? I\'m used to the class syntax but don\'t understand the differences between them exactly.
The main differences between classes and constructor functions are:
Classes can’t be called without new, but functions intended as constructors can (and their this will be wrong)
'use strict';
function Foo() {
console.log(this);
}
class Bar {
constructor() {
console.log(this);
}
}
Foo();
Bar();
Classes can extend more types than constructors can (like functions and arrays)
'use strict';
function Foo(body) {
Function.call(this, body);
}
Object.setPrototypeOf(Foo, Function);
Foo.prototype = Object.create(Function.prototype);
class Bar extends Function {}
(new Bar('console.log(1)'))();
(new Foo('console.log(1)'))();
Classes’ prototypes are their parents (they inherit static properties); writers of constructor functions usually don’t bother with this
Non-classes can’t extend classes (because they can’t call the parent constructor – see the first point)
'use strict';
class Bar extends Function {}
function Foo() {
Bar.call(this);
}
Object.setPrototypeOf(Foo, Bar);
Foo.prototype = Object.create(Bar.prototype);
void new Foo();
Classes are also scoped like let/const (block scope, temporal dead zone, not redeclareable) rather than like var (function scope, hoisted) or like function declarations (it’s complicated).
In your example, an additional difference is that sayHi is defined by assigning to a new property instead of with e.g. Object.defineProperty, so the property’s properties differ from those in the class example in that sayHi is enumerable in the former but not the latter.
function UserA(name) {
this.name = name;
}
UserA.prototype.sayHi = function () {
alert(this.name);
};
class UserB {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let a = [];
let b = [];
for (let key in new UserA()) a.push(key);
for (let key in new UserB()) b.push(key);
console.log(a, b);