Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Creating classes using constructors is not only too similar to writing ordinary functions, but the code is not easy to understand
In ES6 (ECMAScript2015) the new standard uses the class keyword to define classes directly
But classes are essentially just syntactic sugar for a chain of constructors and prototypes
The creation of a class
Classes can be declared in two ways: class declarations and class expressions
Class declaration
class Person {}
Copy the code
Such expressions
const Person = class {}
Copy the code
The characteristics of the class
class Person {}
console.log(Person.prototype) / / = > {}
console.log(typeof Person) // => function
const per = new Person()
console.log(per.__proto__ === Person.prototype) // => true
Copy the code
Class constructor
When we use constructors to create instances, we often need to pass in parameters
In a class, the declaration of the class is separated from the constructor of the class
Each class can have its own constructor (method), whose name is the fixed constructor
When we operate on a class using the new operator, the class’s constructor is called
If we do not display the constructor that declares the class, the following default constructor exists
constructor() {}
Copy the code
When we declare our own constructor, we override the default constructor and start using our own constructor
Each class can have only one constructor, and if it contains multiple constructors, an exception is thrown
The constructor does the same thing you do when you create a function using the ES5 constructor
- Create a new object in memory (empty object)
- The [[prototype]] property inside this object will be assigned to the prototype property of the class
- The this inside the constructor points to the new object being created
- Internal code to execute the constructor (function body code)
- If the constructor does not return a non-empty object, the new object created is returned
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
const per = new Person('Klaus'.23)
console.log(per) // => { name: 'Klaus', age: 23 }
Copy the code
Methods of a class
Instance methods
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
// The methods defined here are methods on instances of the class
// These methods are defined on the class's prototype
running() {
console.log('running')}}const per = new Person('Klaus'.23)
per.running() // => running
Person.prototype.running() // => running
Copy the code
Accessor method
class Person {
// Define private attributes
#address = 'Shanghai'
constructor(name, age) {
this.name = name
this.age = age
}
// Accessors -- get
get address() {
return this.#address
}
// Accessors -- Settings
set address(v) {
this.#address = v
}
}
const per = new Person('Klaus'.23)
console.log(per.address) // => Shanghai
per.address = 'Guangzhou'
console.log(per.address) // => Guangzhou
Copy the code
A static method
The static methods of a class are also called class methods
Unlike instance methods and accessor methods of a class, static methods of a class are defined on the class itself
You can only call from a class, not an instance of a class
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
static running() {
console.log('running')}}const per = new Person('Klaus'.23)
Person.running() // => runnning
per.running() // error
Copy the code
inheritance
The use of the extends keyword has been added to ES6 to facilitate inheritance
// Superclass
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eatting() {
console.log('eatting')}static running() {
console.log('running')}}// Subclass -- derived class
class Student extends Person {
// If a subclass does not define a constructor, a default constructor exists
// This constructor automatically calls the parent constructor for initialization
/* constructor() { super(... arguments) } */
}
const stu = new Student('Klaus'.23)
console.log(stu.name, stu.age) // => Klaus, 23
// Subclasses inherit instance methods from their parent class
stu.eatting() // => eatting
// Subclasses can also inherit static and accessor methods from their parent class
Student.running() // => running
Copy the code
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eatting() {
console.log('eatting')}static running() {
console.log('running')}}class Student extends Person {
constructor(name, age, sno) {
// Note: Before you can use this in the constructor of a child (derived) class or return the default object (created instance object), you must call the constructor of the parent class through super
super(name, age)
this.sno = sno
}
}
const stu = new Student('Klaus'.23.1810166)
console.log(stu.name, stu.age, stu.sno) // => Klaus, 23, 1810166
Copy the code
rewrite
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eatting() {
console.log('eatting')}static running() {
console.log('running')}}class Student extends Person {
constructor(name, age, sno) {
super(name, age)
this.sno = sno
}
eatting() {
console.log('student eatting')}static running() {
console.log('student running')}}const stu = new Student('Klaus'.23.1810166)
stu.eatting() // => student eatting
Student.running() // => student running
Copy the code
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eatting() {
console.log('eatting')}static running() {
console.log('running')}}class Student extends Person {
constructor(name, age, sno) {
super(name, age)
this.sno = sno
}
eatting() {
// You can use the super keyword to call the corresponding methods (instance methods and static methods) in the subclass.
super.eatting()
console.log('student eatting')}static running() {
super.running()
console.log('student running')}}const stu = new Student('Klaus'.23.1810166)
stu.eatting()
/* => eatting student eatting */
Student.running()
/* => eatting student eatting */
Copy the code
Inherits from built-in classes
Object is the parent of all classes in JS
class Person {}
/ / equivalent to the
class Person extends Obejct {}
// If the parent class is not specified in JS, the parent class is set to Object by default
// The equivalent of extends Obejct is omitted and is the default
Copy the code
So we can also inherit from built-in classes
class CustomArray extends Array {
getFirstItem() {
return this[0]}getLastItem() {
return this[this.length - 1]}}const customArr = new CustomArray(1.2.3)
console.log(customArr.getFirstItem()) / / = > 1
console.log(customArr.getLastItem()) / / = > 3
Copy the code
The class into
JavaScript classes only support single inheritance: that is, they can have only one parent class, but you want to emulate the effects of multiple inheritance in JS
That is, when you inherit a class and then use another method, you can use class mixing
JS itself does not realize the mixing of classes, but it can simulate the mixing of classes through the characteristics of JS functional programming
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
// Methods that need to be mixed in
function running() {
console.log('running')}// Simulate mixin
function mixins(className, mixins) {
class DeliverClass extends Person {}
for (let k in mixins) {
DeliverClass.prototype[k] = mixins[k]
}
return DeliverClass
}
const mixinPerson = mixins('Person', {
running
})
const per = new mixinPerson('Klaus'.23)
console.log(per.name)
console.log(per.age)
per.running()
Copy the code
polymorphism
Polymorphism is the embodiment of the same operation for different data types and different behaviors
That is, variables of different data types call the same function, resulting in different execution effects
// Traditional object-oriented polymorphism has three premises:
// 1> must have inheritance (inheritance is a prerequisite for polymorphism)
// 2> Must have overrides (methods for subclasses to overwrite their parents)
// 3> There must be a parent class reference to a subclass object (variables of subclass type are assigned to variables of subclass type)
/ / parent class
class Shape {
getArea(){}}/ / subclass
class Rectangle extends Shape {
// Override the parent method
getArea() {
console.log('getArea in Rectangle')}}class Cricle extends Shape {
getArea() {
console.log('getArea in Cricle')}}// A parent class reference points to a subclass object
const r: Shape = new Rectangle()
const c: Shape = new Cricle()
r.getArea() // => getArea in Rectangle
c.getArea() // => getArea in Cricle
Copy the code
However, in JS, there are no restrictions on polymorphism as in traditional object-oriented languages
const o = {
getArea() {
console.log('getArea in o')}}function Person() {}
Person.prototype.getArea = () = > console.log('getArea in Person')
const per = new Person()
o.getArea() // => getArea in o
per.getArea() // => getArea in Person
Copy the code
function sum(a, b) {
console.log(a + b)
}
sum(2.3) / / = > 5
sum('abc'.'cba') // => abccba
Copy the code