JS object-oriented implementation

The content of the blog is only personal practical understanding, lack of experience, if there are errors, please correct me!

Object-oriented abstract representation

Object-oriented abstraction refers to the abstract representation of all aspects of any object in the real world in the form of code.

One: ES5 basic object-oriented syntax

function Animal(name) {
    
    
	// 实例属性
    this.name = name+'_animal_tag'
}
// 静态(类)属性/方法:Animal函数对象(类)可以访问定义在该对象上的属性,Animal实例无法访问
Animal.num = 42
Animal.getNum = function () {
    
    
    return Animal.num
}
// 实例方法:Animal实例可以访问Animal原型上的方法(属性搜索遵从原型链机制)
Animal.prototype.getName = function () {
    
    
    return this.name
}
Animal.prototype.setName = function (name) {
    
    
    this.name = name
}
Class instance

Insert picture description here

Two: ES6 basic object-oriented syntax

class AnimalES6{
    
    
    constructor(name) {
    
    
    	// 实例属性
        this.name = name+'_animal_tag'
    }
    // 静态方法(类方法)
    static getNum(){
    
    
        return AnimalES6.num
    }
    // 实例方法
    getName(){
    
    
        return this.name
    }
    setName(name){
    
    
        this.name = name
    }
}
// 静态属性(类属性)
AnimalES6.num = 42
Class instance

Insert picture description here

  • Comparing the ES5 instance structure, it can be seen that the composition and function of the two are basically the same.
  • Obviously ES6's class syntax is syntactic sugar .

Encapsulation of three object-oriented features

The encapsulation of JavaScript classes and instances is essentially paperless (js function objects/ordinary objects are not closed, and all properties and methods are publicly accessible).

One: ES5 package

1._Agreement
// 私有方法
Animal.prototype._bar = function () {
    
    
	// 私有属性
    return this._foo
}
2. Borrowing modular packaging
Animal.prototype.fn= function (foo) {
    
    
    bar.call(this,foo)
}
// 私有方法
function bar(foo){
    
    
// 私有属性
	var foo = foo
}

Two: ES6 package

1. The attribute names and method names beginning with # are regarded as private attributes [proposal, currently unavailable]
class IncreasingCounter {
    
    
  // 私有属性
  #count = 0;
  get value() {
    
    
    console.log('Getting the current value!');
    return this.#count;
  }
  increment() {
    
    
    this.#count++;
  }
}
const counter = new IncreasingCounter();
counter.#count // 报错
counter.#count = 42 // 报错
2._Convention (all properties and methods beginning with an underscore are considered private, and try not to access them from outside)
class Widget {
    
    

  // 公有方法
  foo (baz) {
    
    
    this._bar(baz);
  }

  // 私有方法,外部可访问
  _bar(baz) {
    
    
    return this.snaf = baz;
  }

  // ...
}
3. Defined outside the class + modular encapsulation
class Widget {
    
    
  foo (baz) {
    
    
    bar.call(this, baz);
  }

  // ...
}
// 只在当前模块下可见,其它模块无法访问
function bar(baz) {
    
    
  return this.snaf = baz;
}
4. Symbol + modular encapsulation (use the symbol value visible under the current module as the private attribute name/method name, the private attribute/method name cannot be obtained from the outside for access)
const bar = Symbol('bar');
const snaf = Symbol('snaf');
// 只暴露myClass,不暴露bar和snaf,外部无法调用[bar]方法,但内部方法foo可调用
export default class myClass{
    
    

  // 公有方法
  foo(baz) {
    
    
    this[bar](baz);
  }

  // 私有方法
  [bar](baz) {
    
    
  	// this[snaf]私有属性,模块内可访问
    return this[snaf] = baz;
  }

  // ...
};

Inheritance of three object-oriented characteristics

One: What is inherited?

1. Inherit the static properties and static methods of the parent class
2. Inherit the instance attributes and instance methods of the parent class
3. Inherit the construction method of the parent class

Two: ES6 inheritance

1. Parent category
class AnimalES6{
    
    
    constructor(name) {
    
    
        this.name = name+'_animal_tag'
    }
    static getNum(){
    
    
        return AnimalES6.num
    }
    getName(){
    
    
        return this.name
    }
    setName(name){
    
    
        this.name = name
    }
}
AnimalES6.num = 42
2. Subclass
class CatES6 extends AnimalES6{
    
    
    constructor(name,cry) {
    
    
        super(name)
        this.cry = cry
    }
    getName(){
    
    
        return `[Cat] ${
      
      this.name}`
    }
}
3. Construct and view subclass instances
console.log('-----------ES6继承------------------')
let catES6 = new CatES6('cat','喵喵')
console.log(catES6)

Insert picture description here

4. Analyze subclass instances
  • Does not inherit the static properties of the parent class: num
  • Inherited the properties of the parent class instance: name
  • There is no inheritance but the parent class construction method is called : there is a name attribute on the subclass attribute, and there is no name attribute on the subclass prototype (parent class).
  • Does not inherit the static method of the parent class: getNum
  • Inherited the parent class instance methods: setName, getName

Three: ES5 combined inheritance

1. Parent category
function Animal(name) {
    
    
    this.name = name+'_animal_tag'
}
Animal.num = 42
Animal.getNum = function () {
    
    
    return Animal.num
}
Animal.prototype.getName = function () {
    
    
    return this.name
}
Animal.prototype.setName = function (name) {
    
    
    this.name = name
}
2. Subclass: Prototype chain inheritance
function Cat1(name,cry) {
    
    
    this.name = name
    this.cry = cry
}
Cat1.prototype = new Animal()// Animal构造函数参数无意义
Cat1.prototype.constructor = Cat1 // 将Cat原型上的构造函数从Animal修正回Cat

// 自有方法(自有方法在原型链中优先级更高,可实现重写的目的)
Cat1.prototype.getName = function () {
    
    
    return `[Cat] ${
      
      this.name}`
}
3. Subclass: Construct inheritance
function Cat2(name,cry) {
    
    
    Animal.call(this,name)// 构造继承(子类构造函数调用父类构造函数)
    this.cry = cry
}
Cat2.prototype.getName = function () {
    
    
    return `[Cat] ${
      
      this.name}`
}
4. Subclass: Combination Inheritance
function Cat3(name,cry) {
    
    
    Animal.call(this,name)// 构造继承(子类构造函数调用父类构造函数)
    this.cry = cry
}
Cat3.prototype = new Animal()// Animal构造函数参数无意义
Cat3.prototype.constructor = Cat3 // 将Cat原型上的构造函数从Animal修正回Cat

Cat3.prototype.getName = function () {
    
    
    return `[Cat] ${
      
      this.name}`
}
5. Construct and view the subclass instances of each inheritance method
console.log('-----------ES5原型链继承--------------')
let cat1 = new Cat1('cat1','喵喵')
console.log(cat1)
console.log('-----------ES5构造继承--------------')
let cat2 = new Cat2('cat2','喵喵')
console.log(cat2)
console.log('-----------ES5组合继承--------------')
let cat3 = new Cat3('cat3','喵喵')
console.log(cat3)

Insert picture description here

6. Analyze the inheritance examples of subclasses of each inheritance method
  • Inheritance of instance attributes can be achieved through prototype chain inheritance (for example, the above subclass and parent class have name attributes, but the one on the parent class has no meaning) and methods.
  • Through structural inheritance, it can be achieved that there is no inheritance but the parent class constructor is called
  • The effect of combined inheritance is basically the same as the following ES6 inheritance. It also cannot inherit static properties and methods. The other disadvantage is that there is an invalid call to the parent class constructor .

Polymorphism of the three characteristics of object-oriented

Polymorphism is the same behavior with multiple manifestations

One: ES6 polymorphism

class AnimalES6{
    
    
    constructor() {
    
    }
    cry(){
    
    
        return 'cry'
    }
}
class CatES6 extends AnimalES6{
    
    
    constructor() {
    
    }
    cry(){
    
    
        return 'miao miao'
    }
}
class DogES6 extends AnimalES6{
    
    
    constructor() {
    
    }
    cry(){
    
    
        return 'wang wang'
    }
}
let ani = new AnimalES6()
let cat = new CatES6()
let dog= new DogES6()
ani.cry()
cat.cry()
dog.cry()

Two: ES5 polymorphism

Consistent thinking, ES6 class syntax is more expressive, so I won’t repeat it here

reference

Ruan Yifeng ES6 class

Guess you like

Origin blog.csdn.net/jw2268136570/article/details/105581650