One, prototype object
1.1- Problems with custom constructors
Question: Do the say methods of P and P2 objects have the same memory address?
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function(){
console.log("say hello");
}
}
var p = new Person("zs", 10);
var p2 = new Person("ls", 15);
console.log(p.say===p2.say);
Copy the code
The memory structure of the p object created above:
P2 Memory structure of the object:
Conclusion: For memory resource allocation, it is not necessary to create and allocate a new (identical) function object for each object, and it is better for everyone to share the same function.To solve this problem, we can separate functions from each other, define global functions, and use the function name as the method object:
function Person(name, age) {
this.name = name;
this.age = age;
this.say = say
}
function say(){
console.log("say hello");
}
var p = new Person("zs", 10);
var p2 = new Person("ls", 15);
console.log(p.say===p2.say);
Copy the code
Conclusion: the purpose of sharing the solution is achieved, but there are new problems. The purpose of object-oriented programming is to reduce global variables, and this writing method adds global variables, which conflicts with my programming ideas.
Perfect solution: At this point, I need to create an area in the constructor where I can store my public method prototype objects
1.2- Prototype object definition
Definition: Each constructor has an object associated with it, which is called a prototype object.
Functionality: Each instance object can share properties and methods from its prototype object, reducing memory allocation.
Grammar:
Constructor. Prototype
Get the prototype objectConstructor. Prototype. member name = member value
Method to add members to the prototype object
So, I want to share the same say method in every Person object, and I can do it like this:
function Person(name, age) { this.name = name; this.age = age; } person.prototype. say = function(){console.log("say hello"); }; var p = new Person("zs", 10, say); p.say(); var p2 = new Person("zs", 10, say); p2.say();Copy the code
2. Core concepts in object Orientation
The constructor, Person, and the new keyword create the object
Prototype object: person.prototype,
Instance objects: Objects created by the constructor are called instance objects
Instantiation: The process of creating an instance object by the constructor is called instantiation
Object members: properties + methods
Instance members: Properties and methods on an instance object, name,age, that are accessible only to the current instance object
Stereotype members: Properties and methods on a stereotype object, say(), accessible to all instance objects created using the stereotype object’s corresponding constructor
Static members: Properties and methods that are added directly to a constructor and are accessible only by the constructor
The method of obtaining the prototype object
3.1 the -__ proto __ attribute
Definition: There is a __ proto __ attribute on each instance object, which is also used to get the prototype object of the object (this attribute was only included in the specification after ES6, and was only implemented in some browsers before that). .
Syntax: instance object.__ proto __;
Instance object.__ proto __ === constructor.Copy the code
We said earlier that each instance object can share properties and methods on its prototype object
So what’s the rationale for using object… constructor to get the class that is that object?
Conclusion: Instance objects do not have constructor properties, but rather share properties on their prototype objects
The __ proto __ attribute can be viewed as a hieroglyphic. The underscore is not meaningless. It acts as a chain through which I violently pull down the attribute methods that I do not have on my instance object. In this way, we can use a graph to represent the relationship between the constructor, prototype, and instance objects:
3.2 getPrototypeOf method
Definition: Static member methods on the Object constructor.
Syntax: object.getPrototypeof Gets the prototype Object of the specified instance Object
All three methods of getting the prototype object mentioned above give the same result. Object.getprototypeof (p) == person. prototype == p.__ proto __
The constructor creates an instance object supplement
Now that I know more about prototypes, I’ll go back to the details of how constructors create instance objects.
Function Person(name) {var obj = new Object(); // Assign object obj to this this = obj; this.name = name; // Add properties and methods via this // Return the wrapped this object, return this; }Copy the code
That’s what I figured out earlier, but it’s pretty obvious now.
In the function, what I create by default is an Object of type Object, which has nothing to do with the current Person constructor.
If you want to create an object with a specific type, you should have the following steps:
// Set obj's __proto__ attribute to point to the Person constructor's prototype objectCopy the code
//obj.__proto__ = Person.prototype;
Copy the code
Constructor to create an instance object:
- The default inside the function is to create an empty Object — var obj = new Object();
- Set up the
obj.__proto__
Property points to the constructorobj.__proto__ = Person.prototype
; - This — this = obj;
- Add properties and methods with this — this.xx=xx……
- By default, internally created objects are returned — return this;
Setup and access of prototype objects
5.1- Problems encountered in setting up prototypes
The constructor.prototype. Method name = method function is used to set a single public method
Function Person(name, age) {this.name = name; this.age = age; } // Add the method person.prototype. study = function () {console.log(this.name,this.age); Var p = new Person("zs",10); var p2 = new Person("ls",12); p.study(); p2.study();Copy the code
What if you need to add more than one member to a prototype object? One by one? Is the first thought to encapsulate them into an object, as follows:
Person.prototype = { study:function () { console.log(this.name,this.age); }, say:function () { console.log(this.name," say hello"); }}Copy the code
This approach makes adding members to the Person prototype object more consistent and convenient than the previous approach.
Well, here’s the problem!
This code must be written before the instance object is created, otherwise the added members will not be available.
function Person(name, age) { this.name = name; this.age = age; } var p = new Person("zs",10); Person.prototype = { study:function () { console.log(this.name,this.age); } } p.study(); //p.study is not a functionCopy the code
Why is this a problem?
In fact, it is not difficult to understand that when creating p objects, there is no study function in Person and the prototype object of Person, so there is no such function in the created P objects, so this problem is inevitable. Let’s draw a picture to analyze:
Then came the worse problem!
The constructor property of the p object becomes unknown when the object has been created and the methods in the prototype object can be used
The console. The log (p.c onstructor) -- -- -- -- -- -- -- -- -- -- -- -- > ƒ Object () {} [native code]Copy the code
Why is this a problem?
We need to expand on the previous illustrations of constructors, prototype objects, and instance objects
5.2- Access rules for prototype objects
Prove what P. communstructor is:
Constructor ===Object // Constructor ===Object // Constructor ===Object __proto__=== object. prototype // Specify that the constructor of the new prototype Object and its corresponding prototype Object instantiate the ObjectCopy the code
As mentioned earlier, an instance object does not have a constructor property. Instead, it shares properties on its prototype object via __proto__
It’s not on the prototype. What do I do?
Along the__proto__
This chain, you go all the way up until you find this property…
Object. Prototype has a constructor property. Therefore, the p.structor property ultimately returns the constructor of Object. As a result, it is impossible to determine the type.
How to solve the problem:
Add a constructor property to the new prototype object that points to the Person constructor, thus changing the point of p.constructor to get its true type.
Constructor :Person = {constructor:Person, constructor:Person, constructor:Person, constructor:Person, constructor:Person; study:function () { console.log(this.name,this.age); }, say:function () { console.log(this.name," say hello"); }}Copy the code