The writing method in advanced programming is as follows
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
}
Person.prototype = {
constructor: Person,
getName: function(){
return this.name;
}
}
So if I write it like this, is it the same? The only difference is that their constructors are different?
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.lessons = ['Math','Physics'];
Person.prototype.getName = function(){
return this.name;
}
}
What is the difference between writing the prototype definition (location) inside or outside the constructor?
The second way of writing will perform the operation on the prototype every time an instance is created! The point is that this operation is meaningless, and this method is the same for every instance.
In the first method, when the prototype is written outside the constructor, the problem of repeated definition or memory allocation can be solved both formally and through memory allocation.
Corresponding to the first way of writing in memory, no matter how many instances you create, each instance occupies only name, age, job and lessons. There is only one copy of getName in memory, shared by all instances; in the second way of writing, each newly created instance will allocate an extra space (stack) to execute the prototype definition.
What is the difference between the way prototype is assigned values in the first method and the second method?
The big difference is that once a function class is defined, its default constructor property is itself, and its instance will return this value when accessing the constructor property.
Why do you need to define constructor in method 1? Because it reassigns the prototype. If you don’t define constructor (
Person.prototype = {getName: function() {}}
),那么上例中p.constructor
返回值将是Object
, that is, the constructor of p is Object, which is obviously inconsistent with the facts.The more sensible approach in method 1 is not to reassign the prototype, but only add the attribute getName we need to the prototype, and change it to
Person.prototype.getName = function() {return this.name;}
, which is the definition method in the second method. This way, the default attributes of the prototype will not be overwritten.The former way of writing rewrites the prototype, and your way of writing just adds a method to the prototype. The two are different ways
According to the way you write it, storage space will be reallocated to the instance during each instantiation process. One of the meanings of the prototype pattern is that all instances can share the attributes and methods on the prototype, although doing so alone has flaws. The second point is that I still prefer to write the prototype object object literal. I personally think that one is more intuitive, and the second is conducive to maintenance. As follows:
Be sure to write the constructor attribute, otherwise a pointing error will occur. At this time, the prototype object is rewritten. If this attribute is not specified, the prototype chain will not be able to play its due role.
There are many differences between prototypal inheritance and constructors. Prototypal inheritance is prototype chain inheritance.
The prototype chain is not perfect, it contains the following two problems.
In view of this, in practice the prototype chain is rarely used alone.
To this end, there will be some attempts below to make up for the shortcomings of the prototype chain.
Borrow constructor
In order to solve the above two problems in the prototype chain, we started to use a technique called borrowing constructors (constructor stealing) (also called classic inheritance).
Obviously, borrowing constructors solves the two major problems of the prototype chain in one fell swoop:
First, it ensures the independence of reference type values in the prototype chain and is no longer shared by all instances;
Second, when creating a subtype, you can also pass parameters to the parent type.
Following this, if you only borrow the constructor, you will not be able to avoid the problems of the constructor pattern - the methods are all defined in the constructor, so function reuse is not available. And supertypes (such as Father ) are also invisible to subtypes. Considering this, the technique of borrowing constructors is rarely used alone.
For more information, please refer to JS Prototype Chain and Inheritance. Don’t be confused anymore. Just click if you like it. Like and support, thank you!