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:

  1. Constructor. PrototypeGet the prototype object
  2. Constructor. Prototype. member name = member valueMethod 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:

  1. The default inside the function is to create an empty Object — var obj = new Object();
  2. Set up theobj.__proto__Property points to the constructorobj.__proto__ = Person.prototype;
  3. This — this = obj;
  4. Add properties and methods with this — this.xx=xx……
  5. 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