Constructor, prototype, prototype chain in JS
In typical OOP languages (such as Java), there is the concept of a class, a class is the template of an object, an object is an instance of a class, but before ES6, JS did not have the concept of a class
1. There are three ways to create an object:
1. Object literals
let obj = {}
Copy the code
2,new Object()
let obj = new Object()
Copy the code
3. Custom constructors
function person (name, age) {
this.name = name
this.age = age
this.sayName = function () {
console.log(this.name)
}
}
let p1 = new person('Jerry', 18)
Copy the code
2. Constructor
A constructor is a special function used to initialize an object, that is, to assign initial values to its member variables. It is always used with new. We can extract some common properties and methods from objects and encapsulate them in this function.
Note when using constructors:
1. The constructor is used to create a class of objects whose first letter is capitalized
2. Constructors are used with new
When executed, new does the following four things:
Create a new empty object in memory
2. Make this point to the new object
Execute the code inside the constructor to add properties and methods to the new object
4, return the new object (so no return is needed in the constructor)
Constructor members can be added, either to the constructor itself or to this inside the constructor. Members added either way become static members or instance members, respectively
- Static member: A member added to the constructor itself that can only be accessed by the constructor itself
- Instance member: An object member created inside a constructor that can only be accessed by the instantiated object
function Person(name, age) { this.name = name this.age = age this.sayName = function () { console.log(this.name) } } // Instance members are the members added inside the constructor via this: Let p1 = new Person('Jerry', 18) person. gender = 'male' // static member, Gender => Static member console.log(person.gender) //male => Static member console.log(p1.gender) // undefined => static member console.log(p1.gender) // undefined => Cannot be accessed through objectsCopy the code
3. Constructors
The constructor method is nice, but it can be a waste of memory
function Person(name, age) {
this.name = name
this.age = age
this.sayName = function () {
console.log(this.name)
}
}
let p1 = new Person('Jerry', 18)
let p2 = new Person('Jack', 19)
console.log(p1.sayName === p2.sayName) // false
Copy the code
When creating instance objects, for simple data types, assign values directly. For complex data types, when creating instance objects p1, a separate space is allocated for the complex data type sayName method. When creating object P2, a separate space is allocated for the complex data type sayName method. Two Spaces are created to store the same function
We want all objects to use the same function to save memory. How do we do that?
4. Constructor prototype
Constructors The functions assigned by stereotypes are shared by all objects
Js specifies that each constructor has a Prototype property that points to another object. Prototype is an object whose properties and methods are all owned by the constructor.
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayName = function () {
console.log(this.name)
}
let p1 = new Person('Jerry', 18)
let p2 = new Person('Jack', 19)
console.log(p1.sayName()) // Jerry
console.log(p2.sayName()) // Jack
console.log(p1.sayName === p2.sayName) // true
p1.__proto__ === Person.prototype // true
Copy the code
In general, common attributes are defined in constructors, and common methods are placed on prototype objects.
What is a prototype: an object that we also call prototype object
What is a prototype for: Shared methods
Object prototype __proto__
Each object has a __proto__ attribute that points to the prototype object constructor. Objects can use the properties and methods of the prototype object constructor because the object has a __proto__ prototype
- The __proto__ object prototype is equivalent to the prototype object prototype
- The __proto__ object prototype is meant to provide a direction, or a route, for object look-up mechanisms, but it is a nonstandard attribute and therefore cannot be used in actual development. It only points internally to the prototype object
6. The constructor function
Both proto and constructor objects have a constructor property inside. Constructor we call it a constructor because it refers to the constructor itself
Contructor is mainly used to record which constructor the object refers to, and it can redirect the prototype object to the original constructor
Function Person(name, age) {this.name = name this.age = age} Person. Prototype = { You must manually refer back to the original constructor using constructor: Person, sayName: function () { } } let p1 = new Person('Jerry', 18) let p2 = new Person('Jack', 20) console.log(Person.prototype.constructor) console.log(p1.__proto__.constructor)Copy the code
Normally, the object’s methods are set in the constructor’s prototype object. If we have multiple object methods, we can assign the prototype object as an object, but this overwrites the original constructor object so that the modified prototype object constructor no longer points to the current constructor. At this point, we can add a constructor pointing to the original constructor in the modified prototype object
Relationships among constructors, instances, and prototype objects
8. Prototype chain
1, any object has a __proto__ prototype, pointing to the prototype object
2. The __proto__ prototype in the Person prototype Object points to Object.prototype
Prototype __proto__ is null. If it is an Object, there is a prototype __proto__ in it. If it is a prototype Object, there is a __proto__ in it. The Object prototype Object also has a __proto__ in it, which points to null
To put it simply, each object has a prototype, and each prototype is an object, so the prototype has its own prototype, so that one ring links one ring to form a chain, which is called the prototype chain
9. Member lookup mechanism of Js (rules)
1. When accessing properties (including methods) of an object, first look up whether the object itself has the properties
2, if not, find its prototype (i.e. the prototype object __proto__ points to).
3. Find the prototype of the prototype Object if it hasn’t already
4, and so on until Object (null)
5. The point of __proto__ object archetypes is to provide a direction, or a route, for the object member lookup mechanism
10. The prototype object this points to
This in the constructor refers to the instance object
Inside the prototype object is a method, and the “this” in this method refers to the caller of this method, that is, the instance object. Depending on how this is called, it refers to our caller
Bind (), call(), apply() 1, call() method: call an object, that is, call a function, change this reference to the function. The main role is to implement inheritance
foo.call(thisArg, arg1,arg2,....)
Copy the code
2, the apply() method: calls a function, that is, the way the function is called, and changes the function’s this pointer
foo.apply(thisArg, [argArray])
Copy the code
ThisArg: Specifies this value when foo is run
ArgArray: The value passed must be contained in the array
The return value is the return value of the function, because it is the calling function
Var arr = [1,20,30,60] var Max = math.max. Apply (Math, arr) MaxCopy the code
3. The bind() method does not call the function, but can change the this reference inside the function
foo.bind(thisArg, arg1, arg2,.....)
Copy the code
ThisArg: Specifies this value when foo is run
Arg1, arg2: Other arguments to pass
Returns a copy of the original function modified by the specified this value and initialization argument, that is, the new function created after the original function changed this
var btn = document.querySelector('button'); btn.onclick = function() { this.diabled = true; Var that = this; SetTimeout (function() {setTimeout(function() {this.disabled = false; this.disabled = false; }.bind(this), 3000); // This refers to the object BTN}Copy the code
Conclusion:
- Call () often does inheritance
- Apply () is often associated with arrays
- Bind () does not call a function immediately. If there is a function we do not need to call immediately, but we want to change the reference to this inside the function, we use bind().
11. Built-in objects
You can use prototype objects to extend custom methods on built-in objects, such as adding custom sums to arrays
Array.prototype.sum = function () {
let sum = 0
for (let i = 0; i < this.length; i++) {
sum += this[i]
}
return sum
}
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(arr.sum())
console.log(Array.prototype)
Copy the code
Array.prototype = {}, array.prototype. XXX = function (){}.