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,greet
Properties andmsg
Property is to belong toFo
Instance object, and seeprintMsg
andprintGreet
These two methods:
printGreet
At this point info
the__proto__
On thatFo.prototype
On;- And because
Fo.prototype
And pointed to theFoo
Instance object of, soFo.prototype
It’s actually pointing toFoo
Of the instance object of; - And finally you can see
printMsg
Is hanging onFoo.prototype
On 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.