- In JavaScript, a class is a kind of a function.
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let user = new User("John");
user.sayHi();
- The definition class User {...} create such function and puts the methods into User.prototype.
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// proof: User is a function
alert(typeof User); // function
// proof: User is the "constructor" function
alert(User === User.prototype.constructor); // true
// proof: there are two methods in its "prototype"
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
- Just like functions, classes can be defined inside another expression, passed around, returned etc.
function makeClass(phrase) {
// declare a class and return it
return class {
sayHi() {
alert(phrase);
};
};
}
let User = makeClass("Hello");
new User().sayHi(); // Hello
- Classes have some differences compared to regular functions:
- Constructors require
new
- Unlike a regular function, a class
constructor
can’t be called without new.
- Different string output
- If we output it like
alert(User)
, some engines show "class User..."
, while others show "function User..."
.
- Please don’t be confused: the string representation may vary, but that’s still a function, there is no separate “class” entity in JavaScript language.
- Class methods are non-enumerable
- A class definition sets
enumerable
flag to false
for all methods in the "prototype"
.
- That’s good, because if we
for..in
over an object, we usually don’t want its class methods.
- Classes have a default
constructor() {}
- If there’s no
constructor
in the class
construct, then an empty function is generated, same as if we had written constructor() {}
.
- Classes always
use strict
- All code inside the class construct is automatically in strict mode.
- Classes also include getters/setters, generators, computed properties etc.
class User {
constructor(name) {
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("Name is too short.");
return;
}
this._name = value;
}
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name too short.
Class Inheritance
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stopped.`);
}
}
// Inherit from Animal
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.hide(); // White Rabbit hides!
- The extends keyword actually adds a [[Prototype]] reference from Rabbit.prototype to Animal.prototype.
- Class syntax allows to specify not just a class, but any expression after
extends
.
- That may be useful for advanced programming patterns when we use functions to generate classes depending on many conditions and can inherit from them.
- For instance, a function call that generates the parent class: