1, Relationship between constructor and prototype object:
There is a Star constructor. Each constructor has a prototype object, which is pointed to by the prototype of the constructor
Similarly, there is also a property called constructor in the prototype object, which refers back to the constructor
The constructor can be regarded as the father. The father points to the prototype object of his son through the prototype, tells others that I have a powerful son called the prototype object, and there is an attribute constructor in the prototype object, and points back to the constructor, saying that I have a powerful father. They flatter each other
2, Relationship between constructor, instance object and prototype object:
We can create an instance object through the constructor. As long as the constructor is new, an instance object can be generated, so the constructor can point to the object instance. We know that there is also a prototype in the instance object__ proto__, This__ proto__ It points to the Star prototype object. Of course, there is also a constructor in our object instance, which can refer back to the constructor
3, Prototype chain
As long as it's an object__ proto__ Prototype, pointing to prototype object
Inside the prototype object__ proto__ The prototype points to object prototype
function Star(uname,age){ this.uname = uname; this.age = age; } Star.prototype.sing = function(){ console.log("I can sing"); } var zxz = new Star('Zhang Xinzhe',18); // As long as it's an object__ proto__ Prototype, pointing to prototype object console.log(Star.prototype); console.log(Star.prototype.__proto__ === Object.prototype);// true // In our Star prototype object__ proto__ The prototype points to object prototype console.log(Object.prototype.__proto__); // Our object Prototype prototype object__ proto__ The prototype point is null
4, JavaScript object member lookup mechanism (rule)
-
When accessing the properties (including methods) of an object, first find out whether the object itself has the property
-
If not, find its prototype (that is, the prototype object pointed to by _proto _)
-
If not, find the prototype of the prototype Object (the prototype Object of the Object)
-
And so on until the Object is found (null)
-
__ proto__ The significance of object prototype is to provide a direction or a route for the object member search mechanism.
var that; function Star(name,age){ // In the constructor, this refers to the instance object this.name = name; this.age = age; } Star.prototype.sing = function(){ // this in the prototype object function refers to the instance object and mxq object that = this; console.log("I can sing"); } // Star.prototype.sex = "female" Object.prototype.sex = "female" var mxq = new Star("Meng Xiaoqi",18) // mxq.sex = "female" console.log(mxq.sex);// Output female mxq.sing(); console.log(that === mxq);// true
Prototype object this point: In the constructor, inside this Refers to an instance object In prototype object functions this,Refers to an instance object
5, Extending built-in objects with prototype objects
You can extend and customize the original built-in object through the prototype object. For example, add a custom even sum function to the array.
Note: array and string built-in objects cannot override the operation array Prototype = {}, can only be array prototype. XXX = function() {}.
Array.prototype.sum = function(){ var total = 0 for(var i=0;i<this.length;i++){ total += this[i] } return total; } var arr = [5,6,7]; arr.sum(); // 18
6, Inherit
ES6 did not provide us with extensions inheritance before. We can implement inheritance through constructor + prototype object simulation, which is called composite inheritance. We use prototype chain to inherit prototype properties and methods, and borrow constructor technology to inherit instance properties.
1. Borrowing constructors to inherit parent type properties
Core principle: point this of the parent type to this of the child type through call(), so that the child type can inherit the properties of the parent type.
call() function: call this function and modify the point of this when the function runs
fun.call(thisArg,arg1,arg2,...)
thisArg: currently calling the pointing object of function this.
arg1,arg2: other parameters passed
function fn(x,y){ console.log(this); console.log("I want to go out"); console.log(x+y) } var obj = { name:"Meng Xiaoqi" } fn();// this points to the window. I want to go out and play // call() can call a function fn.call();// this points to the window. I want to go out and play // call() can change this point of this function, and this point of this function points to obj fn.call(obj,1,2);// {name: "cute seven"} I want to go out and play 3
Example: borrow the parent constructor to inherit properties
function Father(name,age){ // this points to the object instance of the parent constructor this.name = name this.age = age } function Son(name,age,score){ // this points to the object instance of the child constructor Father.call(this,name,age) this.score = score } var son = new Son("Meatball",18,98) console.log(son); // Output: Son {name: "small ball", age: 18, score: 98}
At this point, the child constructor inherits the properties of the parent constructor
2. Using prototype object inheritance method: son prototype = new Father();
function Father(name,age){ // this points to the object instance of the parent constructor this.name = name this.age = age } function Son(name,age,score){ // this points to the object instance of the child constructor, which copies the properties of the parent class to the Son instance Father.call(this,name,age) this.score = score } Father.prototype.money = function(){ console.log("Father wants to make money") } // Son.prototype = Father.prototype // If the child prototype object is modified, the parent prototype object will change with it Son.prototype = new Father(); // If you modify the prototype object in the form of an object, don't forget to use the constructor to refer back to the original prototype object Son.prototype.constructor = Son Son.prototype.school = function(){ console.log("Children have to go to school") } var son = new Son("Meatball",18,98) console.log(son); console.log(Father.prototype);
advantage:
The methods of the parent class can be reused
The reference properties of the parent class are not shared
When a subclass builds an instance, it can pass parameters to the parent class
Disadvantages:
First call to Father(): to son Prototype writes two attributes, name and age.
The second call to Father(): write two attributes name and age to instance1.
Two properties on the instance object son mask its prototype object son Two properties of prototype with the same name. Therefore, the disadvantage of composite mode is that when using subclasses to create instance objects, there will be two properties / methods of the same parent class instance in its prototype. This coverage results in a waste of performance.
Parasitic combinatorial inheritance (optimal scheme)
Composite inheritance has the disadvantage of wasting by calling the constructor of the parent class twice. Parasitic composite inheritance can solve this problem.
The core lies in inheritPrototype(son, father), which allows the prototype of the subclass to point to the copy of the prototype of the parent class, so that the constructor of the parent class will not be called, resulting in a waste of memory.
function inheritPrototype(son, father) { // Fixed the sub class prototype object pointer to point to a copy of the parent class prototype (object() is also acceptable) son.prototype = Object.create(father.prototype) // Enhance the object to compensate for the loss of the default constructor attribute due to rewriting the prototype son.prototype.constructor = son } function Father(name,age){ // this points to the object instance of the parent constructor this.name = name this.age = age } function Son(name,age,score){ // this points to the object instance of the child constructor, which copies the properties of the parent class to the Son instance Father.call(this,name,age) this.score = score } Father.prototype.money = function(){ console.log("Father wants to make money") } inheritPrototype(Son, Father) Son.prototype.school = function(){ console.log("Children have to go to school") } var son = new Son("Meatball",18,98) console.log(son); console.log(Father.prototype);
[reprint] https://mp.weixin.qq.com/s/FZTgakDp-jQc1Ic4NT7WYg