Prototype objects are also not without drawbacks. First, it omits the process of passing initialization parameters to the constructor, resulting in all instances getting the same property value by default. While this will somehow bring some inconvenience, it's not the biggest problem with prototype objects. The biggest problem with prototype objects is caused by the nature of their sharing.
all of the properties in the prototype are shared by many instances , and the share is appropriate for the function. It makes sense for those attributes that contain basic values, after all (as shown in the previous example), by adding a property of the same name on the instance, you can hide the corresponding attribute in the prototype. However, for attributes that contain reference type values, the problem is more prominent . Take a look at the following example.
functionPerson () {}person.prototype={constructor:person, Name:"Nicholas", Age:29, Job:"Software Engineer", friends: ["Shelby", "Court"], Sayname:function() {alert ( This. Name); }};varPerson1 =NewPerson ();varPerson2 =NewPerson ();p Erson1.friends.push ("Van"); alert (person1.friends); //"Shelby, Court, Van."alert (person2.friends);//"Shelby, Court, Van."Alert (person1.friends = = = Person2.friends);//true
Here, the Person.prototype object has a property named Frends that contains an array of strings. Then, two instances of person are created. It then modifies the array referenced by Person1.friends and adds a string to the array. Because the friends array exists in Person.prototype instead of Person1, the changes are also reflected by the person2.friends (which points to the same array as the Person1.friends). If our intention is to share an array in all instances like this, there is nothing to say. However, the example is generally to have all of their own properties. And that's why we rarely see people using prototypes alone.
The most common way to create custom types is to use constructors and prototypes together. Constructors are used to define instance properties , and prototypes are used to define methods and shared properties . As a result, each instance will have its own copy of the instance properties, but at the same time it shares a reference to the method, saving the memory to a minimum. The following code overrides the previous example.
functionPerson (name, age, Job){ This. Name =name; This. Age =Age ; This. Job =job; This. Friends = ["Shelby", "Court"];} Person.prototype={Constructor:person, sayname:function() {alert ( This. Name); }}varPerson1 =NewPerson ("Nicholas", "Software Engineer");varPerson2 =NewPerson ("Greg", "Doctor");p Erson1.friends.push ("Van"); alert (person1.friends); //"Shelby, Count, Van"alert (person2.friends);//"She1 By,count"Alert (person1.friends = = = Person2.friends);//falseAlert (Person1.sayname = = = Person2.sayname);//true
In this example, the instance properties are defined in the constructor, and the properties constructor and Method Sayname () shared by all instances are defined in the prototype. modifying Person1.friends (Adding a new string to it) does not affect person2.friends, because they refer to different arrays respectively.
This pattern of constructors and prototypes is the most widely used and most recognized method of creating custom types in ECMAScript. It can be said that this is a default pattern for defining reference types.
JavaScript prototype chain Learning (iii) problems and combinations of prototype objects using constructors and prototypes