Object-oriented programming
Object orientation is a programming idea that is often compared to procedure orientation.
At its simplest, process-oriented focus is on verbs, figuring out the steps needed to solve a problem, and then writing functions to implement each step, followed by calling the functions in turn. The focus of attention to the object is subject and predicate, which is to disassemble the things that constitute the problem into various objects. The purpose of disassembling the objects is to realize a certain step, but to describe the various behaviors of the thing in the current problem.
Object-oriented features:
1. Encapsulation allows people to use objects not to consider the internal implementation, only to consider the use of the function to protect the internal code, only leaving some API interfaces for users to use.
2, inheritance is to code reuse, from the parent class inherited some methods and attributes, subclasses also have their own properties
3. Polymorphism is the effect of different objects on the same operation. The idea of polymorphism is actually to separate “what do you want to do” from “who’s going to do it
When is it appropriate to use object orientation
It can be seen that in the face of complex problems, or when there are more participants, object-oriented programming ideas can simplify the problem very well, and can be better extended and maintained.
Object orientation in Js
Objects contain methods and properties
Create an object
1. Common way
const Player = new Obejct();
Player.color = "white"
Player.start = function() {
console.log('start')}Copy the code
The factory pattern
function createObject() {
const Player = new Obejct();
Player.color = "white"
Player.start = function() {
console.log('start')}return Player
}
Copy the code
Constructor/instance
Properties and methods added via this always point to the current object, so they are copied in memory during instantiation, thus wasting memory.
But the advantage of this is that even if you change the properties or methods of one object, the other objects will not be affected (because each object is copied).
function Player(color) {
this.color = color
this.start = function() {
console.log(color)
}
}
const player1 = new Player('red')
const player2 = new Player('blue')
console.log(player1 === player2) // false Memory is created multiple times
Copy the code
3, the prototype
The method of inheriting through the prototype is not in itself, we have to look up the prototype chain layer by layer. The advantage of this method is that it is created only once in memory, and all instantiated objects point to the prototype object.
function Player(color) {
console.log(color)
}
Player.prototype.start = function() {
console.log(color)
}
const player1 = new Player('red')
const player2 = new Player('blue')
console.log(player1.start === player2.start) // true
Copy the code
4. Static properties are property methods that are bound to constructors and need to be accessed by constructors
function Player(color) {
this.color = color
if(! Player.total) { Player.total =0
}
Player.total++
}
const player1 = new Player('red')
console.log(Player.total)
const player2 = new Player('blue')
console.log(Player.total)
Copy the code
Prototypes and prototype chains
function Player(color) {
console.log(color)
}
Player.prototype = {
start: function() {
console.log('start')},revert: function() {
console.log('revert'}} Find the Player prototype objectconst Player1 = new Player('red')
const Player2 = new Player('blue')
console.log(Player1.__proto__) // === player. prototype {start: ƒ, revert: ƒ}
console.log(Object.getPrototypeOf(Player1)) // Player.prototype {start: ƒ, revert: ƒ}
Object. Get __proto__ getPrototypeOfconsole.log(Player.__proto__) // [Function]
Copy the code
The flow chart
The new keyword
- A new object, Player1, inherited from Player.prototype, is created
- Player1. Proto pointing Player. The prototype
- Point this to the newly created object Player1
- Return new object
- If the constructor does not explicitly return a value, return this
- If the constructor has an explicit return value of a basic type, such as number,string, Boolean, then return this
- If the constructor has an explicit return value of an object type, such as {a: 1}, then the object {a: 1} is returned.
function proPlayer() {
return {a: 1}}const pro1 = new proPlayer()
console.log(pro1) // {a: 1}
function proPlayer() {
return 123
}
const pro1 = new proPlayer()
console.log(pro1) // proPlayer {}
function proPlayer() {
return
}
const pro1 = new proPlayer()
console.log(pro1) // proPlayer {}
Copy the code
Implement new
function objectFactory() {
let obj = new Object(a);let Constructor = [].shift.call(arguments)
obj.__proto__ = Constructor.prototype
let result = Constructor.apply(obj, arguments)
return typeof result === "object" ? result : obj;
}
Copy the code
Prototype chain
We all know that when you read the properties of an instance, if you can’t find them, you look for the properties in the stereotype associated with the object, and if you can’t find them, you look for the stereotype of the stereotype, all the way to the top.
function Player() {}
Player.prototype.name = 'Tom'
let p1 = new Player()
p1.name = 'Davi'
console.log(p1.name) // Davi
delete p1.name
console.log(p1.name) // TomIf we can't find the name attribute in player.prototype, we'll look for it in player.prototype.__proto__ ({}).delete Player.prototype.name
console.log(p1.name)
Copy the code
inheritance
1. Prototype chain inheritance
function Parent() {
this.name = 'parentName'
}
Parent.prototype.getName = function() {
console.log(this.name)
}
function Child() {}
Child.prototype = new Parent()
Child.prototype.constructor = Child
let child1 = new Child()
child1.getName()
Copy the code
Disadvantages:
1. If an instance modifies an attribute that is a reference type, all instances are affected
2, the instance of the instance to create, cannot pass parameters
function Parent() {
this.actions = ['parentName'.'play']}function Child() {}
Child.prototype = new Parent()
Child.prototype.constructor = Child
let child1 = new Child()
let child2 = new Child()
child1.actions.pop()
console.log(child1.actions) //parentName
console.log(child2.actions) //parentName
Copy the code
2. Constructor
function Parent(name, actions) {
this.actions = actions;
this.name = name;
this.eat = function() {
console.log(name)
}
}
function Child(id, name, actions) {
Parent.call(this, name); Parent.apply(this, array.from (arguments).slice(1));
this.id = id;
}
const child1 = new Child(1."c1"["eat"]);
const child2 = new Child(2."c2"["sing"."jump"."rap"]);
console.log(child1.name); // { actions: [ 'eat' ], name: 'c1', id: 1 }
console.log(child2.name);
console.log(child1.eat === child2.eat)
Copy the code
Cons: Waste of memory
Combination of inheritance
function Parent(name, actions) {
this.name = name;
this.actions = actions;
}
Parent.prototype.eat = function () {
console.log(`The ${this.name} - eat`);
};
function Child(id) {
Parent.apply(this.Array.from(arguments).slice(1));
this.id = id;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
function Child(id) {
Parent.apply(this.Array.from(arguments).slice(1));
this.id = id;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Copy the code
Disadvantages: Constructor is called twice
Parasitic combination inheritance
function Parent(name, actions) {
this.name = name;
this.actions = actions;
}
Parent.prototype.eat = function () {
console.log(`The ${this.name} - eat`);
};
function Child(id) {
Parent.apply(this.Array.from(arguments).slice(1));
this.id = id;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
const child1 = new Child(1."c1"["hahahahahhah"]);
const child2 = new Child(2."c2"["xixixixixixx"]);
Copy the code