2
头图

Three characteristics of object-oriented:

Inheritance, encapsulation, polymorphism

inherit:
  • When it comes to inheritance, it involves class. My understanding: a class is an abstraction of the common properties and methods of one or some things.
  • Then inheritance is the superficial meaning, to inherit the properties and methods described by his parent class, and allow it to extend, rewrite, etc.
Encapsulation

It is to box the system modules, hide the internal implementation, and only expose to the external call interface

Polymorphism

There are multiple states, multiple different implementations of the

In other words, a method or interface of a parent class is inherited and overridden by multiple subclasses. In this way, a method of the parent class has multiple manifestations in the subclass, forming polymorphism

Object Orientation of JS

Overview

  • Object-oriented is a kind of thought, or programming mode
  • It is different from process-oriented. Process-oriented focuses on the process of development, while object-oriented focuses on who the participants are and how to participate?
JS object-oriented mechanism of , (li) , (shi) now ( yi) , (liu)
  • For JS, everything is an object. There are certain historical reasons for this-because when the author of JS, Brendan Eich, was developing JS, object-oriented programming ideas were flooding
  • The browsers at that time were so rudimentary that Brendan Eich didn't want to write JS so formal/complicated. It only needed to meet the simplest browser-user interaction requirements, such as-fill in a username
Brendan Eich's approach 1--new constructor
  • He referred to other languages and found that inheritance was achieved through the constructor of the new class. Then he adopted a simplified method: discarding the class and allowing the new constructor to get the instance object directly in JS. This implementation inherits.

, I don’t write about it, just play~

  • But-this method has a -cannot share properties and methods , or the instance object created by this method inherits only the value, not the address

    • This means that if there are 5 attributes to be inherited, each occupying 10 memory, if 100 instance objects need to be created, then the memory consumed by these attributes alone is: 5 10 100, which is not friendly to performance
    • In addition, if an instance object adds or modifies an attribute, other instance objects will not be affected.
In order to solve this shortcoming--
Brendan Eich's approach 2-the introduction of prototype attributes
  • Set a prototype property for the constructor dedicated to store instance objects. Those properties and methods that do not need to be shared are still placed in the constructor.
  • In this way, the properties and methods of the instance object are divided into two types, is not shared, and the other is shared .
The new keyword is completely inherited,
  • It is actually a encapsulated function, and its core mechanism is setPrototypeOf() and apply()
  • When an instance object is new, it will be "Automatically reference" the properties and methods of the prototype object by calling setPrototypeOf() (get the properties and methods stored in the prototype object)
  • and then call the apply() method, (get the properties and methods stored in the constructor)
This is the prototype mode
  • Used for create instance object , which realizes high-performance inheritance .
  • When inheritance is required, an object is allowed to directly clone an existing prototype object to quickly generate a new object instance like it. All object instances will share all the properties and methods of the prototype object

Understand the prototype mode, it is easy to understand the prototype and the prototype chain--
prototype and prototype chain

Prototype

Each function (constructor) has a prototype property, which itself is a reference, pointing to an object called prototype object , which contains the properties shared by by the same constructor. And method

can be simply understood: the prototype is a template, can be inherited by cloning it

Tips: A constructor (including itself), and all instance objects created by it share a prototype object by reference, (because in JS, the function itself is an object)

Implicit prototype __proto__
  • Each objects has a __proto__ property, point prototype object in its constructor
  • means: its value === the value of [[Prototype]] of its constructor

Let's take a chestnut, it's easy to understand--

let constructor = function () {};
let obj = new constructor();
console.log(obj.__proto__ === constructor.prototype);
//true

A : The correct way to write the attribute "__proto__" is Two underscores on each side "_"
After ES6, it is more recommended to use Object.getPrototypeOf/Reflect.getPrototypeOf and Object.setPrototypeOf/Reflect.setPrototypeOf

not recommended to use this attribute directly:

why?

  • Because of the double underscore before and after __proto__, it means that it is essentially an internal property, not a formal external API. It was only added to ES6 due to the extensive support of browsers.
  • No matter from a semantic point of view or from a compatibility point of view, do not use this property, but use the following Object.setPrototypeOf() (write operation), Object.getPrototypeOf() (read operation), Object.create() ( Generate operation) instead.
Obj.constructor properties

Is a property of another object, it points to the object's constructor

function company() {
  this.name = " name";
  this.address = "address";
}
let obj = {};
Object.setPrototypeOf(obj, company.prototype);
console.log(obj.constructor === company); //true
// 和obj.__proto__联动一波,增进理解
console.log(obj.__proto__ === obj.constructor.prototype); //true

Prototype chain

Each object has a __proto__ attribute to point to the prototype object of its constructor , 1609b51a454429 and then prototype object is also an object, and also has the __proto__ attribute... and then it keeps null (the root or tail of the chain is null), which forms a prototype chain

Prototype chain query

When accessing a property of an object, if there is no such property inside the object, it will look for the prototype object pointed to by its __proto__ property. If it still cannot be found, it will continue to the parent's constructor. Find in the prototype object...until the top of the prototype chain is null

This process is very similar to the execution context and scope chain

How many ways does JS implement inheritance?

1. Constructor + apply inheritance

function company() {
  this.name = " name";
  this.address = "address";
}
let obj = {};
company.apply(obj);
console.log(obj);
//{ name: ' name', address: 'address' }
Only the attributes in the constructor can be inherited, and the attributes on the prototype of the constructor and the prototype chain cannot be inherited, as follows ↓
function company() {
  this.name = " name";
  this.address = "address";
}
company.prototype.phone = 110;
let obj = {};
company.apply(obj);
console.log(obj.phone); //undefined

2.prototype prototype inheritance

Prototype inheritance is more efficient and memory-saving, and also more JS

function company() {
  this.name = " name";
  this.address = "address";
}
company.prototype.phone = 110;
let obj1 = {};
let obj2 = {};
Object.setPrototypeOf(obj1, company.prototype);
Object.setPrototypeOf(obj2, company.prototype);
console.log(obj1.phone === obj2.phone && obj1.phone === 110);//true
Only inherit the prototype object (prototype) of the constructor and the properties on the prototype chain, and cannot inherit the properties inside the constructor
console.log(obj1.name); //undefined

3.new keyword inheritance

Overview

  • JS actually has no concept of class . The so-called class is simulated by the constructor. When we use the new keyword, or ES6's Class keyword, we feel that the concept of "class" is very similar to java. But in fact, the underlying implementation mechanism of the new and class keywords is still based on the prototype , which is syntactic sugar.
So how is class inheritance implemented in JS?
  • That is, the constructor is used as the parent class, and then through the call and apply methods, the environment of this is changed, so that the subclass can obtain various attributes of the parent class. It can be said that part of the reason why ES6 introduced call and apply methods is to better object-oriented.

Note:

  • The this object in a JS function is like an implicit parameter of a function, or reference
  • In fact, the new keyword-is a encapsulated function, and its internal mechanism is a combination of the first and second methods above, so this method combines the advantages of the two, and can completely inherit the internal properties of the Attributes in + Attributes on the prototype chain
function company() {
  this.name = "Billie";
  this.address = "address";
}
company.prototype.phone = 110;
let obj1 = new company();
let obj2 = new company();
console.log(obj1.phone === obj2.phone && obj1.phone === 110);
console.log(obj1.name === obj2.name && obj1.name === "Billie");
// true
Let’s look at a slightly more complicated chestnut
In the function object, apply is used to call the constructor of the parent class, so that it can obtain the methods and properties of the parent class (parent constructor) * *
var father = function() {
  this.age = 52;
  this.say = function() {
    alert('hello word');
  }
}
 
var child = function() {
  this.name = 'bill';
  father.call(this);
}
 
var man = new child();
man.say();

In the above code, first, the new keyword is executed internally to - let result = child.apply(man, null);
Will call the child function, and then replace this directly with man, like this↓

var child = function() {
  man.name = 'bill';
  father.call(man);
}
var man = new child();
man.say();

Then, the call method is executed, and in the same way, the father method is executed and the this is replaced by man--

var father = function() {
  man.age = 52;
  man.say = function() {
    alert('xxx');
  }
}

Then, those properties and methods already exist in the man object, so just call man.say() directly

Or-flexible use of Object.create() method, obj.constructor attribute

Object.create() method
  • Logic: This method will create a new object, and use the passed in object as the __proto__ of the newly created object, and then return this new object
  • Parameters: Object
  • Return value: object

Therefore, it may be another way to create an instance of an object, you can flexible use it

function company() {
  this.name = "Billie";
  this.address = "address";
}
company.prototype.phone = 110;
let obj1 = Object.create(company.prototype);
//这样就和第2种继承方法一样了
console.log(obj1.__proto__ === company.prototype);
console.log(obj1.phone);
console.log(obj1.name);
//true
//110
//undefined
obj.constructor attribute

As for the constructor property, you can flexible use the way to achieve inheritance between constructors (because there are only a function of the property)

function Parent() {
  this.name = 'parent5';
  this.play = [1, 2, 3];
}
function Child() {
  Parent.call(this);
  this.type = 'child5';
}
// 产生一个中间对象隔离`Child`的`prototype`属性和`Parent`的`prototype`属性引用的同一个原型。
Child.prototype = Object.create(Parent.prototype); 
// 给Child的原型对象重新写一个自己的constructor。
Child.prototype.constructor = Child;

Reference:
The design idea of Javascript inheritance mechanism-Ruan

JS object-oriented?

"What does the new operator in JS do?" 》--Crushdada's shimo Notes

's understanding of JS prototype and prototype chain--CSDN

JS prototype inheritance and class inheritance

What is this in JavaScript? What did it do?

Several ways of JS inheritance

is the difference and relationship between __proto__ and prototype in 1609b51a469780 js?


Crushdada
146 声望3 粉丝