In object-oriented programming, a class is an extensible program code template for creating an object that provides an initial value for its state (member variables) and an implementation of its behavior (member functions or methods).
In daily development, we often need to create many objects of the same type, such as users, goods, or anything else.
As we learned in the constructor and operator “new” chapter, new Function can help with this requirement.
But in modern JavaScript, there’s a more advanced “class” construction that introduces a lot of cool new features that are useful for object-oriented programming.
“Class” syntax
The basic syntax is:
class MyClass {
/ / a class method
constructor() {... } method1() { ... } method2() { ... } method3() { ... }... }Copy the code
Then use new MyClass() to create a new object with all the methods listed above.
New automatically calls the constructor() method, so we can initialize objects from constructor().
Such as:
When new User(“John”) is called:
- A new object is created.
constructor
Run with a given parameter and assign itthis.name
.
… Then we can call object methods, such as user.sayhi.
A common pitfall for novice developers is to place commas between the methods of a class, which can lead to syntax errors.
Do not confuse the notation here with object literals. In a class, you don’t need a comma.
What is class?
So, what exactly is class? As one might think, this is not an entirely new language-level entity.
Let’s demystify it and see what a class really is. This will help us understand many complex aspects.
In JavaScript, a class is a function.
Take a look at the following code:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }}// Support: User is a function
alert(typeof User); // functionCopy the code
class User {… } the constructor actually does the following:
- Create a file named
User
The function becomes the result of the class declaration. The code for this function comes fromconstructor
Method (if we do not write this method, it is assumed to be empty). - Store methods in a class, for example
User.prototype
In thesayHi
.
When the new User object is created, when we call its methods, it gets the corresponding method from the prototype, as we explained in the chapter F. ProtoType. Therefore, the object New User can access methods in the class.
We can interpret the result of the class User declaration as:
The following code explains them nicely:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }}// class is a function
alert(typeof User); // function
/ /... Or, more specifically, the constructor method
alert(User === User.prototype.constructor); // true
// The method is in user.prototype, for example:
alert(User.prototype.sayHi); // alert(this.name);
There are actually two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHiCopy the code
It’s not just grammar sugar
It is often said that class is a syntactic sugar (a syntax designed to make things easier to read without introducing anything new) because we can actually declare the same thing without class:
// Rewrite class User as a pure function
// 1. Create constructor function
function User(name) {
this.name = name;
}
// Any function prototype has a constructor attribute by default,
// So, we don't need to create it
// 2. Add methods to the prototype
User.prototype.sayHi = function() {
alert(this.name);
};
/ / usage:
let user = new User("John");
user.sayHi();Copy the code
The result of this definition is essentially the same as the result of using the class. So this is really a reason to think of class as a syntactic sugar for defining constructors and their prototypical methods.
There are important differences, though:
-
First, functions created by class have special internal attribute tags [[FunctionKind]]:”classConstructor”. Therefore, it is not exactly the same as manual creation.
Unlike normal functions, class constructors must be called with the new keyword:
In addition, the string representation of class constructors in most JavaScript engines is “class…” At the beginning
-
Class methods are not enumerable. The class definition sets enumerable to false for all methods in “Prototype”.
This is good, because if we call for.. In methods, we usually don’t want class methods.
-
The class always uses Use strict. All code in class construction is automatically put into strict mode.
In addition, the class syntax brings a number of other features that we’ll explore later.
Such expressions
Just like functions, classes can be defined, passed, returned, assigned, etc., in another expression.
Here is an example of a class expression:
let User = class {
sayHi() {
alert("Hello"); }};Copy the code
Similar to Named Function Expressions, class Expressions should probably also have a name.
If a class expression has a name, that name is visible only inside the class:
// "Named Class Expression"
// (there is no such term in the specification, but it is similar to named function expressions)
let User = class MyClass {
sayHi() {
alert(MyClass); // The name MyClass is only visible inside the class}};new User().sayHi(); // Display the contents defined in MyClass
alert(MyClass); // error, MyClass is not visible externallyCopy the code
We can even create classes dynamically “on demand”, like this:
Getters/setters and other shorthand
Like object literals, classes might include getters/ Setters, computed properties, and so on.
Here is an example of implementing user.name using get/set:
class User {
constructor(name) {
/ / call the setter
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 is too short.Copy the code
The class declaration creates getters and setters in user.prototype like this:
Object.defineProperties(User.prototype, {
name: {
get() {
return this._name
},
set(name) {
// ...}}});Copy the code
This is a […] Has an example of computed property name in
class User {['say' + 'Hi']() {
alert("Hello"); }}new User().sayHi();Copy the code
The Class attribute
Class-level attributes were recently added to the language.
In the example above, User only has methods. Now we add an attribute to it:
The name attribute is not put in user.prototype. Instead, it is created through a new point before the constructor is called, and it is a property of the object itself.
conclusion
The basic class syntax looks like this:
class MyClass {
prop = value; / / property
constructor(...). {/ / the constructor
// ...
}
method(...) {} // method
get something(...) {} / / getter method
set something(...) {} / / setter methods
[Symbol.iterator]() {} // There is a way to calculate names (symbol here)
// ...
}Copy the code
Technically, MyClass is a function (the one we provide as constructor), while methods, getters, and settors are all written to MyClass.prototype.
In the next chapter, we’ll learn more about classes, including inheritance and other functionality.
A little chestnut
Degree of importance: *****
The Clock class is written functionally. Please rewrite it in “class” syntax.
The P.S. clock ticks in the console and can be viewed when opened.
class Clock {
constructor({ template }) {
this.template = template;
}
render() {
let date = new Date(a);let hours = date.getHours();
if (hours < 10) hours = '0' + hours;
let mins = date.getMinutes();
if (mins < 10) mins = '0' + mins;
let secs = date.getSeconds();
if (secs < 10) secs = '0' + secs;
let output = this.template
.replace('h', hours)
.replace('m', mins)
.replace('s', secs);
console.log(output);
}
stop() {
clearInterval(this.timer);
}
start() {
this.render();
this.timer = setInterval((a)= > this.render(), 1000); }}let clock = new Clock({template: 'h:m:s'});
clock.start();Copy the code