Prototypes for JS and inheritance related concepts

After ES6, JavaScript has been able to implement object-oriented writing through class, extends, and other syntactic sugar, but the previous prototype objects must also be understood.

The constructor

Before we talk about prototypes, it’s important to understand that in the old object-oriented way, objects in JavaScript are obtained through constructor instances:

function Fo(msg) {
  this.msg = msg
}
Copy the code

Person is a constructor, usually with a capital letter. There are two parameters, name and sex, assigned to the this object.

In this case, we can obtain an instance of Person by using the new operation:

const f = new Foo('Hello')
console.log(f.msg)  // Hello
Copy the code

(MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG) {if (MSG);

var obj = {}
obj.__proto__ = Person.prototype
Person.call(obj)
return obj
Copy the code

2. __proto__ and prototype

Prototype objects and prototype chains

__proto__ : Each instance object has this property, corresponding to the constructor’s prototype function;

Prototype: Each constructor has a prototype object.

The following graph shows the relationship between the two:

As you can see, the instance object’s __proto__ refers to its constructor’s prototype, and the JavaScript feature of using a property or method is to look for the property or method to call on the current instance object. If not, Then look to the instance object’s proto** (the constructor’s prototype object) until it finds or reaches null at the top level. 天安门事件

And from the code, you can see that they are exactly equal:

console.log(f.__proto__ === Fo.prototype) // true
Copy the code

__proto__ => Fo. Prototype => Fo. Prototype. __proto__ => object. prototype => null.

inheritance

There are two types of inheritance in JavaScript. The first is inheritance of attributes, which can be implemented through the call method. The second is inheritance of methods, which need to be implemented through the prototype chain.

function Foo(msg) { this.msg = msg } Foo.prototype.printMsg = function () { console.log(this.msg) } function Fo(msg, greet) { Foo.call(this, msg) this.greet = greet } Fo.prototype = new Foo() Fo.prototype.constructor = Fo Fo.prototype.printGreet = function () {  console.log(this.greet) } const fo = new Fo('Hello', 'How are you? ') console.log(fo)Copy the code

Print this FO and you can see the following image:



Obviously,greetProperties andmsgProperty is to belong toFoInstance object, and seeprintMsgandprintGreetThese two methods:

  1. printGreetAt this point infothe__proto__On thatFo.prototypeOn;
  2. And becauseFo.prototypeAnd pointed to theFooInstance object of, soFo.prototypeIt’s actually pointing toFooOf the instance object of;
  3. And finally you can seeprintMsgIs hanging onFoo.prototypeOn the prototype object.

Therefore, we can see that when we access fo object properties, itself on the instance object, can be directly accessed; __proto__ (fo. Prototype) is found on Foo instance object. According to the characteristics of prototype chain, when the corresponding method cannot be accessed, it will be found on __proto__ attribute (foo. prototype) of Foo instance object, so the method inheritance is implemented.

conclusion

In fact, JavaScript objects are created by the new constructor, which is already handled internally by the new constructor; Inheritance is realized through the characteristics of the prototype chain. The prototype of the “subclass” points to the instance object of the “superclass”. In this way, when looking through the prototype chain, it will naturally find from the subclass to the superclass.