Constructor
The function that instantiates an object through the new function name is called a constructor.
Any function can exist as a constructor. The reason why there are constructors and ordinary functions is mainly different in function. The main function of constructors is to initialize objects, which is characterized by using them together with new. New is creating an object from scratch. The constructor is adding properties and methods to the initialized object. Constructors are defined with an uppercase initial (canonical).
function Person(name) { this.name = name; } let p1 = new Person('Zhang San'); // instantiation console.log(p1); // Person {name: "Zhang San"}
At this point, p1 is a new object.
1. What happened in the process of creating a new object?
- Create an empty object obj {}
- Empty object_ proto_ Points to the prototype member object of the constructor
- Using apply to call the constructor function, properties and methods are added to the object referenced by this
- If there is no other object returned in the constructor, return this, that is, the new object of the created. Otherwise, return the object returned in the constructor
Understanding of new: new applies for memory and creates objects. When new is called, the background will implicitly execute new Object() to create objects. Therefore, the strings and numbers created through new are reference types, but non value types.
2. Handwritten new function
function _new(func, ...args) { // 1. Create an empty object let obj = {}; // 2. Of empty objects_ proto_ Points to the prototype member object of the constructor obj.__proto__ = func.prototype; // One or two steps of merging is equivalent to let obj = Object.create(func.prototype) // 3. Use apply to call the constructor function, and the properties and methods are added to the object referenced by this let result = func.apply(obj, args); // 4. Make sure that new comes out with an object return typeof result === 'object' ? result : obj; }
Test case:
function Person(name, age) { this.name = name; this.age = age; } let obj = _new(Person, 'xia', 20); console.log(obj); // Person {name: "xia", age: 20}
3. Method on constructor
- Define methods directly on constructors (not shared)
function Person() { this.say = function () { // Direct definition method console.log('hello'); } } let p1 = new Person(); let p2 = new Person(); p1.say(); // hello p2.say(); // hello console.log(p1.say === p2.say); // false
Obviously, p1 and p2 don't point to the same place. Therefore, this method is used to add methods to the constructor to generate instances. Each time an instance is generated, a new memory space is opened to store methods. This can lead to a great waste of memory and affect performance.
- Add method through prototype (shared)
Constructors are functions allocated through prototypes and are shared by all objects.
function Person(name) { this.name = name; } Person.prototype.say = function () { // Adding methods through prototypes console.log('hello ' + this.name); } let p1 = new Person('Zhang San'); let p2 = new Person('Li Si'); p1.say(); // hello Zhang San p2.say(); // hello Li Si console.log(p1.say === p2.say); // true
Therefore, we often define public attributes in constructors and put public methods on prototype objects.
Click to view“ Five inheritance methods of constructor"
prototype
1. What is a prototype?
The above Person.prototype is the prototype (also known as explicit prototype). It is an object, which we also call prototype object.
2. What is the role of prototype?
The role of prototypes is to share methods.
Through Person.prototype.say, we can share methods without repeatedly opening up storage space and reducing memory waste.
3. What is the direction of this in the prototype?
Point to instantiated objects p1 and p2
Function object
- __Proto: any object (everything in JS is an object) has the proto attribute (implicit prototype)
- Prototype: all functions (functions only) have the prototype attribute (explicit prototype)
- Constructor: all prototype and instantiated objects have a constructor attribute, which points to the associated constructor itself
When we declare a method with function keyword, we will add a prototype property for this method, which points to the default prototype object, and the constructor property of this prototype also points to the method object. These two properties will be referenced by the property of the object when creating the object.
function Hello() {}; // Constructor var h = new Hello(); // Instantiate object // All functions have a prototype attribute (explicit prototype) console.log(Hello.prototype); // Object {} prototype object // The prototype property of the constructor has a constructor property that points to the constructor itself console.log(Hello.prototype.constructor === Hello); // true // The instantiated object does not have the prototype attribute, and only the function has the prototype attribute console.log(h.prototype); // undefined // The constructor property of the instantiated object points to the constructor itself console.log(h.constructor === Hello); // true // Namely console.log(h.constructor === Hello.prototype.constructor); // true // All reference types have the _proto attribute (implicit prototype) console.log(h.__proto__ === Hello.prototype); // true // Namely console.log(h.__proto__ === h.constructor.prototype); //true // Namely console.log(Hello.prototype === h.constructor.prototype); //true // Namely console.log(Hello === h.constructor); // true
1. prototype
All functions (functions only) have the prototype attribute (explicit prototype)
function Person() {}; Person.prototype.sayHello = function() { console.log('Hello!') } var person1 = new Person(); var person2 = new Person(); console.log(person1.sayHello === person2.sayHello) // true, the same method
The prototype object is used to put the shared properties and methods of an instance of the same type. In essence, it is for the sake of memory.
At this point, you need to know that all functions themselves are instance objects of Function functions, so there will also be a prototype object in the Function function Function to put its own shared properties and methods of instance objects.
// The constructor property of the instantiated object points to the constructor itself console.log(person1.constructor === Person); // true console.log(person2.constructor === Person); // true // Person is an instance object of a Function console.log(Person.constructor === Function); // true console.log(Function.constructor === Function); // true
As shown below:
2. _proto _
Any object (everything in JS is an object) has the _proto _attribute (implicit prototype)
function Person() {}; Person.prototype.sayHello = function() { console.log('Hello!') } var person1 = new Person(); var person2 = new Person(); // All reference types have a _proto _ attribute that points to the display prototype of the constructor console.log(person1.__proto__ === Person.prototype); // true console.log(person2.__proto__ === Person.prototype); // true
/*1,Literal mode*/ var a1 = {}; console.log(a1.constructor === Object); // true (constructor Object) console.log(a1.__proto__ === a1.constructor.prototype); // true console.log(a1.__proto__ === Object.prototype); // true /*2,Constructor mode*/ var A = function (){}; var a2 = new A(); console.log(a2.constructor === A); // true (constructor function A) console.log(a2.__proto__ === a2.constructor.prototype); // true console.log(a2.__proto__ === A.prototype); // true /*3,Object.create()mode*/ var a1 = {a:1} var a2 = Object.create(a1); console.log(a2.constructor === Object); // true (constructor Object) console.log(a2.__proto__ === a1); // true console.log(a2.__proto__ === a2.constructor.prototype); //false
3. constructor
All prototype and instantiated objects have a constructor attribute, which points to the associated constructor itself
function Person() {}; var person1 = new Person(); var person2 = new Person(); console.log(person1.constructor === Person); // true console.log(Person.constructor === Function); // true console.log(Function.constructor === Function); // true
- person1 and person2 are instances of the person object, and their constructor points to the constructor that created them, that is, the person function;
- Person is a Function, but it is also a Function instance object. Its constructor points to the constructor that created it, that is, the Function function;
- Function function, which is the built-in object of JS, and its constructor is itself, so the internal constructor attribute points to itself.
Therefore, the constructor property is actually a property used to save its constructor reference. There is no other special place.
Prototype chain
var A = function () {}; var a = new A(); // Prototype chain composed of _proto console.log(a.__proto__ === A.prototype); // true console.log(A.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__ === null); // True null means "no object", that is, there should be no value there.
The chain structure composed of interrelated prototypes in the figure below is the prototype chain, that is, the blue line
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.say = function () { console.log('hello', this.name); }; let student = new Person('Zhang San', 18); console.log(student.__proto__ === Person.prototype); // true console.log(student.__proto__.say === Person.prototype.say); // true console.log(student.__proto__.say === student.say); // true console.log(student.say === Person.prototype.say); // true
The reason why an object can use the constructor prototype object's properties and methods is that the object has a _proto _prototype
function Parent(month){ this.month = month; } var child = new Parent('Ann'); console.log(child.month); // Ann console.log(child.father); // undefined
When finding an attribute in child, the following steps are performed:
The access link is:
Ultimate graph
If you understand this figure, the prototype and prototype chain will be basically understood.