summary
In typical OOP languages (such as java), the concept of class exists. Class is the template of object, but the concept of class was not introduced into JS before ES6 (ECMAscript6.0 released in 2015)
Before that, objects were not created based on classes, but used a special function called constructor to define objects and their characteristics
Basic introduction to constructor:
Constructor
case
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.jn = function () { console.log("sleep"); }; } let x = new Zwjs('shaco',18,'male'); console.log(x); x.jn()
member
Some members can be added to the constructor of javascr, either on the constructor itself or on this inside the constructor. The members added through these two methods are called static members and instance members respectively
Static members: members added to the constructor itself are called static members and can only be accessed by the constructor itself
Instance member: object members created inside the constructor are called instance members and can only be accessed by instantiated objects
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.jn = function () { console.log("sleep"); }; } let x = new Zwjs('shaco',18,'male'); // Instance members are members added through this inside the constructor // For example, name age sex jn above is an instance member // Instance members can only be accessed through instantiated objects // as console.log(x.name); // We cannot access instance members through constructors //as // console.log(zwjs.name); report errors // A static member is a member added to the constructor itself Zwjs.lol = 'silver'; // Because js is a dynamic language, we can add languages dynamically, so we can add attributes // Such added objects are static members // Static members can only be accessed through constructors console.log(Zwjs.lol); // Cannot be accessed through instantiated objects // console.log(x.lol0);//undefined
Constructor problem
Although the constructor is easy to use, there are still problems
When we use the constructor, we will open up a new memory space
But because we often use functions as methods in our objects, and functions are complex data types, when we use constructors many times, we will open up a new memory space to store the same function
The example is as follows. We use the constructor to create two objects
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.jn = function () { console.log("sleep"); }; } let x = new Zwjs('shaco',18,'male'); let y = new Zwjs('yasuo', 18 ,'male'); console.log(x.jn===y.jn);
But their methods are not equal, because the storage method of complex data types is to put the address on the stack and the actual object on the heap, so they are not equal
In short, if constructors are widely used, they will constantly open up a lot of space to store the same function, resulting in a waste of memory and a great impact on performance
So at this time, we can use the prototype object to solve it
Prototype object prototype
In js, each constructor has a prototype attribute pointing to another object
It should be noted that prototype itself is an object
All the methods and properties of this object will be owned by the constructor
We can put public methods into prototype objects
The function allocated by the constructor through the prototype is shared by all objects
Therefore, we can define some invariant methods directly on the prototype object, so that all instances of the object can share these methods
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } // console.dir(Zwjs); Zwjs.prototype.jn = function (){ console.log('Just meal'); } let shaco =new Zwjs('shaco',18,'male'); let yasuo =new Zwjs('yasuo',19,'male'); shaco.jn(); yasuo.jn()
As shown in the above code, we created jn this method using the prototype object
Then instantiate two objects
And let them use this method. Let's see how it turns out
It shows that we have realized the sharing of methods
Generally, our public attributes are defined in the constructor
(such as name, age and other attributes in the above code)
The public method is defined on the prototype object
(such as jn method defined by prototype object)
Object prototype__ proto__
It can also be written as []
Instantiated objects have a property__ proto__ Point to the prototype object prototype in the constructor,
The reason why we can use the constructor prototype to prototype the properties and methods of the object is because the instantiated object has the prototype of the proto object
Simply put, the of instantiating objects__ proto__ (object prototype) is the same as the prototype object prototype of the constructor
Object prototype__ proto__ The meaning of is to provide a direction or a route for the object search mechanism, but the object prototype is a non-standard attribute, so we can't use this attribute in the actual development process
Its function is to point to the prototype object prototype from the inside of the object
Prototype constructor
Object prototype prototype and prototype object__ proto__ There is a property constructor in
We call a constructor a constructor because it refers back to the constructor itself
We print that their constructor attribute points to the constructor we started with
effect
For example, when we use object prototypes to store multiple methods and functions, we often write them in the form of objects to make the structure clearer
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } Zwjs.prototype = { sleep: function () { console.log('sleep'); }, eat: function () { console.log('Just meal'); } }
Then we print the constructor of the prototype object of the constructor again
We found that he did not point to our constructor, but to an object
To avoid possible errors, we can call the constructor property to make the prototype object point to our original constructor
Prototype chain
Because each object has its own prototype, what is the object prototype of our prototype object
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } console.log(Zwjs.prototype.__proto__);
The results are as follows. We can understand them as built-in objects
So let's upgrade the prototype chain
We are printing the constructor of the built-in object
console.log(Object.constructor);
Get a constructor
So we can finish the prototype chain again
Let's try the prototype of the built-in object. What is the object prototype of the object
console.log(Object.prototype.__proto__);
obtain
Thus, the prototype chain is completed
Member lookup mechanism of JavaScript
When we access the properties or methods of an object, we first find out whether the object itself has such properties or methods
If not, find the object prototype (that is, instantiate the object and use the prototype object _ proto _ to find the object prototype prototype in the prototype)
If not, find the prototype of the built-in object (the prototype object of the built-in object)
Finally, if it is not found, it returns underfind or null
The case is as follows
We annotate x.sex
We are commenting on zwjs prototype. Sex = 'female'
Finally, we comment out object prototype. Sex = 'human demon';
this point of prototype object
The first thing we need to understand is
this in the constructor refers to the object instance
We create a variable x without assigning a value
Then add the method to make it equal to this, so we instantiate the object and call the method in the prototype object
x equals this
Then print separately
The representation of this (get the constructor, and then because the constructor points to the object instance)
So we print whether this is equal to the instance object to get true
function Zwjs(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } let x ; Zwjs.prototype.jn = function (){ console.log('Just meal'); x=this; } let shaco =new Zwjs('shaco',18,'male'); let yasuo =new Zwjs('yasuo',19,'male'); shaco.jn() console.log(x); console.log(x===shaco);