preface
Many of the previous articles on prototypes had arrow diagrams, which made me feel dizzy, but this time I hope to give everyone a thorough understanding of prototypes and prototype chains through the simplest of words. We all know that JavaScript and Java have similar names, but the two are completely unrelated. In JavaScript, there is no concept of class. In order to reuse JavaScript, inheritance is implemented in the form of prototype and prototype chain. Subsequent ES6 introduced syntactic sugar for classes, which are essentially objects and can be called pseudo-classes. Pseudo-classes are modeled after class-based languages, producing objects through constructor functions. So today’s story starts with constructors.
The constructor
What is a constructor
The difference between a constructor and a normal function is the use of the new operator
function Person (name,age){
this.name = name
this.age = age
}
Copy the code
The above function is just a normal function that can only be called a constructor if it is applied to a new object.
So why is it possible to produce objects with the new operator? What happens in the new operation?
1. Implicitly create an object in the constructor header
2. Assign the scope of the constructor to the new object, and point this, which used to point to window, to the constructed object
3. Return this object (if the function contains a return, it is not an object)
function Person (name,age){
this.name = name
this.age = age
return 1
}
new Person('tim'.18) // Person {name: "tim", age: 18}
Copy the code
If it is a non-object, the constructed object is returned
function Person (name,age){
this.name = name
this.age = age
return {tim:18}}new Person('tim'.18) // {tim:18}
Copy the code
If it is a return object, return the object of return
The role of the constructor
As we mentioned at the beginning, the so-called class is used to describe the attributes and behaviors in things. The characteristics of a class are composed of members, and the attributes correspond to the member variables in the class, while the methods correspond to the member methods in the class. The object we construct through the constructor satisfies this requirement.
function Person (name,age){
this.name = name
this.age = age
this.eat = function (food){
console.log('I ate it today'+food)
}
}
var tim = new Person('tim'.18)
var cope =new Person('cope'.18)
Copy the code
When we use the same constructor, the constructed objects will have some of the same properties and methods, and the properties and methods that all instances have can be placed on the prototype of the function in addition to the constructor body, for instance inheritance.
The prototype
prototype
Every JavaScript function object has a property called prototype.
function Man (name,age){
this.name = name
this.age = age
}
Man.prototype.sex = 'male'
Man.prototype.needCompanion = true
var tim = new Man('tim'.18)
var cope =new Man('cope'.18)
console.log(tim.sex,cope.sex) //male male
Copy the code
In the example above we have completed an instance of inheritance. Tim and Cope both inherit the property sex from the prototype
We can say that Tim and Cope are based on the man.prototype object
So what else is in this object? Let’s print this object on the console
{
"sex": "male"."needCompanion": true."constructor": ƒ Man (the name, age),"__proto__": Object
}
Copy the code
We found that in addition to sex and needCompanion, which we added ourselves, Prototype had two properties in the console, and that these two properties, which are still lightly colored in the console, indicate that they are implicit.
Based on what prototype is we try to demystify constructor and __proto__
constructor
Constructor builder is the translation of meaning, we can find that Man. The prototype. The constructor is pointing to Man the constructor.
Because the object is actually a pointer in JS, all we can find that Man and Man. The prototype. The constructor is exactly the same
console.log(Man === Man.prototype.constructor) //true
Copy the code
__proto__
What is this property for? Take a look at the code below
console.log(tim.__proto__ === Man.prototype) //true
Copy the code
The prototype and constructor functions of an instance can find each other via the constructor and prototype functions. How can an instance find its prototype via the __proto__ attribute?
Every object has a __proto__ attribute, including numeric types, Boolean types, and so on
The new operator we mentioned above 👆 also generates implicit objects during the new process__proto__
The attribute points to the stereotype of the constructor, which is the complete instantiation. So that’s pretty much the content of the prototype, just a little bit more understanding
Prototype chain
For null and undefiend types, there are no __proto__ attributes, and the others have __proto__ attributes. This is a chain structure, just like the scope chain, until the head is found.
tim.__proto__ === Man.prototype
tim.__proto__.__proto__ === Object.prototype
tim.__proto__.__proto__.__proto__ === null
Copy the code
When accessing an attribute on an instance, it looks first to see if the attribute is present on the instance, and when the object does not have the attribute, it looks first to see if it is present on the __proto__ index. If it is not present, it continues to look up __proto__, which is the prototype chain.
Write in the last
This is the fifth article of this series, goo goo goo is quite long, every time I write an article, THERE will be some harvest, I hope I can be a hard-working pigeon. The next article is going to talk about this, the following article, I will try to find some representative topics, so that after learning can be consolidated, so we see 👋 next time.