Design Ideas of Javascript Inheritance Mechanism
I have always had a hard time understanding the inheritance mechanism of the Javascript language.
It does not have the concept of “subclass” and “parent class”, nor the distinction between “class” and “instance”. It relies on a very peculiar “prototype chain” mode. Implement inheritance.
I spent a lot of time studying this part and made a lot of notes. But all belong to forced memory and cannot be understood fundamentally.
It wasn’t until yesterday that I read the explanation of French programmer Vjeux , and I realized that I fully understood why Javascript was designed in this way.
Below, I try to use my own language to explain its design philosophy. Thoroughly explain what is going on with white prototype objects. In fact, it is not that complicated at all, the truth is very simple.
1. Speaking from ancient times
To understand the design philosophy of Javascript, we must start with its birth.
In 1994, Netscape released version 0.9 of the Navigator browser. This was the first relatively mature web browser in history and it was a sensation. However, this version of the browser can only be used for browsing and does not have the ability to interact with visitors. For example, if there is a column of “user name” on the webpage that requires filling in, the browser will not be able to determine whether the visitor really filled it out, and only let the server side judge it. If it is not filled in, the server will return an error and ask the user to fill it out again, which is a waste of time and server resources.
Therefore, Netscape urgently needs a web scripting language to enable browsers to interact with web pages. Engineer Brendan Eich is responsible for developing this new language. He feels that there is no need to make the design complicated. It is enough for this language to be able to complete some simple operations, such as judging whether the user has filled out a form.
1994 was the most prosperous period of object-oriented programming. C++ was the most popular language at the time, and version 1.0 of the Java language was about to be launched the following year. Sun was making a big splash.
Brendan Eich is undoubtedly affected. All data types in Javascript are objects, which is very similar to Java. However, he immediately ran into a problem. Should he design an “inheritance” mechanism?
Second, Brendan Eich’s choice
If it is really a simple scripting language, there is no need to have an “inheritance” mechanism. However, Javascript is all objects, and there must be a mechanism to connect all objects. Therefore, Brendan Eich finally designed “inheritance”.
However, he does not intend to introduce the concept of “class”, because once there is a “class”, Javascript is a complete object-oriented programming language, which seems a bit too formal and increases the difficulty of entry for beginners. .
He considered that both C++ and Java languages use the new command to generate examples.
C++ is written as:
ClassName *object = new ClassName(param);
Java is written as:
Foo foo = new Foo();
Therefore, he introduced the new command into Javascript to generate an instance object from the prototype object. However, Javascript does not have a “class”, how can it represent a prototype object?
At this time, he thought that C++ and Java would call the constructor of the “class” when using the new command. He made a simplified design. In the Javascript language, the new command is not followed by a class, but a constructor.
For example, there is now a constructor called DOG, which represents the prototype of the dog object.
function DOG(name){
this.name = name;
}
Using new on this constructor will generate an instance of the dog object.
var dogA = new DOG(‘大毛’);
alert(dogA.name); // Da Mao
Note the this keyword in the constructor , it represents the newly created instance object.
Three, the disadvantages of the new operator
There is a disadvantage of using constructors to generate instance objects, that is, they cannot share properties and methods.
For example, in the constructor of the DOG object, set the common property species of an instance object.
function DOG(name){
this.name = name;
this.species =’Canine’;
}
Then, two instance objects are generated:
var dogA = new DOG(‘大毛’);
var dogB = new DOG(‘二毛’);
The species properties of these two objects are independent. Modifying one will not affect the other.
dogA.species =’Cat’;
alert(dogB.species); // Show “Canine”, not affected by dogA
Each instance object has its own copy of its properties and methods. This is not only impossible to achieve data sharing, but also a great waste of resources.
Fourth, the introduction of prototype attributes
With this in mind, Brendan Eich decided to set a prototype property for the constructor.
This property contains an object (hereinafter referred to as the “prototype object”). All the properties and methods that need to be shared by the instance object are placed in this object; those properties and methods that do not need to be shared are placed in the constructor.
Once the instance object is created, it will automatically reference the properties and methods of the prototype object. In other words, the properties and methods of instance objects are divided into two types, one is local and the other is referenced.
Take the DOG constructor as an example, and now use the prototype property to rewrite:
function DOG(name){
this.name = name;
}
DOG.prototype = {species:’Canine’ };
var dogA = new DOG(‘大毛’);var dogB = new DOG(‘二毛’);
alert(dogA.species); // Caninealert(dogB.species); // Canine
Now, the species property is placed in the prototype object, which is shared by the two instance objects. As long as the prototype object is modified, two instance objects will be affected at the same time.
DOG.prototype.species =’Cat’;
alert(dogA.species); // catalert(dogB.species); // cat
Five, summary
Since all instance objects share the same prototype object, from the outside world, the prototype object seems to be the prototype of the instance object, and the instance object seems to “inherit” the prototype object.
This is the design idea of Javascript inheritance mechanism. I don’t know if I have made it clear. For the specific application method of the inheritance mechanism, you can refer to the series of articles I wrote:
* “Javascript Object-Oriented Programming (1): Encapsulation”
* “Javascript Object-Oriented Programming (2): Inheritance of Constructor”
* “Javascript Object-Oriented Programming (3): Inheritance of Non-Constructor”
(over)