Js Review (iii)

Stereotypes and prototype chains in JavaScript

object-oriented

There are many design patterns that simplify our code, such as the factory pattern. But in JavaScript, we want to use object-oriented thinking to implement a design pattern to simplify our code, and mimicking the pattern of Java classes to implement classes and inheritance is best.

However, before Es6 there were no class and expend keywords to help us implement.

The implementation class

Before Es6, we used the Function simulation class to mount methods on prototypes

function Dog(name){
  this.name = name
}
Dog.prototype.say = function() {
    console.log("my name is" + this.name);
}
Copy the code

To simulate the New:

function myNew(fn,... Args){let obj={} // Generate object obj.__proto__=fn. Prototype // Link object to constructor prototype fn. Call (obj,... Args) // bind this and execute constructor return obj // return new object}Copy the code

Implementation inheritance

Inheritance is achieved in two main ways

Combination of inheritance

Based on prototype inheritance and constructor inheritance, combinatorial inheritance is proposed. The ability to inherit both stereotypes and properties has become one of the most common inheritance methods in JavaScript

Function Child(value){Father. Call (this,value)Copy the code

Parasitic combinatorial inheritance

Parasitic combination inheritance, the most common inheritance pattern

function inheritPrototype(son, father){ var prototype = Object.create(father.prototype); Prototype. Constructor = son; // Restore the lost default constructor attribute. Prototype = prototype; Function father(name){this.name = name; } father.prototype.sayName = function(){ alert(this.name); }; Function son(name, age){father. Call (this, name); function son(name, age){father. this.age = age; InheritPrototype (son, father); Son.prototype. sayAge = function(){alert(this.age); } var son1 = new son("xyc", 23); // Call the sayName method of the parent class and the sayAge method of the subclassCopy the code

This approach was one of the dominant approaches to inheritance before ES6

Inheritance extends of ES6

The extends keyword acts the same way as in Java, inheriting from a parent class. Note, however, that extends and Class do not fundamentally implement classes and inheritance, but rather encapsulate “syntactic sugar” that is essentially a function. Extends is used with super. Before this, super was the constructor of its parent class.

class Book{ // constructor constructor(weigth) { this.weight = weight; Log () {console.log("open the book")}} Class EnglishBook extends book {constructor(weight,pages){super (weight) this.pages=pages } getPages(){ return this.pages } }Copy the code

It’s worth noting that extends’s core code is the same as parasitic composite inheritance

Extends in Babel:

function _possibleConstructorReturn (self, call) { // ... return call && (typeof call === 'object' || typeof call === 'function') ? call : self; } function _inherits (subClass, superClass) { // ... subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Parent = function Parent () {this _classCallCheck(this, Parent); }; var Child = (function (_Parent) { _inherits(Child, _Parent); function Child () { _classCallCheck(this, Child); return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).apply(this, arguments)); } return Child; }(Parent));Copy the code

This is only part of the code in Bable, but if we look at the _inherits function, we can see that it is implemented much like parasitic composite inheritance. This also shows that parasitic combinatorial inheritance is the best inheritance method nowadays.

Class does not promote variables, and methods in class do not have stereotypes

Prototype chain in JS

When we use objects or arrays in JS, there are many methods and properties we can call. But we have never defined these methods and properties.

When you open console printing, you see that each Object has a __proto__ property that points to the prototype and ultimately to the “ancestor” Object.

Based on this, we can call these object methods.

We can find the prototype using the prototype property in the __proto__ constructor. However, the object in Prototype is basically the same as the object in __proto__.

What’s going on here?

Father. Prototype ===son. Prototype.__proto__

When an object’s property or method is called, if it doesn’t have one, it goes back through the stereotype chain to find the method until it finds one.