Take a look at the following code
function Test() {}
var test = new Test()
console.log(test.name) // undefined
Object.prototype.name = 'hello'
console.log(test.name) // hello
Copy the code
In this example, we define the Test function, create an instance of Test, and print test.name, undefined as expected, but after assigning object.prototype. name, print test.name again as Hello.
Why is that? To understand the inner workings, we need to take a deeper look at prototypes and prototype chains, and get to the point:
The prototype prototype
Functions can have attributes, and each function has a special attribute called prototype, as shown below
function Test() {}
console.log(Test.prototype)
Copy the code
Put it on the console to print, and the following will appear
Prototype has two properties: contructor and __proto__. These two properties will be discussed later, so let’s try adding properties to Prototype
function Test() {}
Test.prototype.name = "Test"
console.log(Test.prototype)
Copy the code
Put it on the console to print, and the following will appear
As you can see, Prototype already has an attribute named name.
So what does this Prototype do?
In fact, we refer to Prototype as a prototype object. An object templates on a prototype object and inherits methods and properties from that prototype object
function Test() {}
var test = new Test()
Test.prototype.name = "Test"
console.log(test.name)
Copy the code
Put it on the console to print, and the following will appear
As you can see, the properties defined in the prototype object are also owned by the instance object test generated by new. Let’s print the instance object test
As you can see, the instance object test has an attribute named __proto__, which holds the name attribute we defined for the prototype object.
So what is __proto__? What is the relationship with Prototype?
__proto__
Test.__proto__ is similar to test.prototype
Test. __proto__ and test. prototype both refer to the same object. They are identical. Go to test.__proto__ to find the name attribute.
In addition to the __proto__ attribute, we find that the test object has a constructor attribute.
The constructor property
Let’s take a look at what the constructor property has
As you can see, the constructor property is very much like the Test function; in fact, each instance object Test inherits a Constructor property from the stereotype that points to the constructor used to construct the instance object, known as Test.
Constructor refers to the test constructor, which means that we can instantiate a new object via the constructor property.
var test2 = new test.constructor()
Copy the code
Normally we would not use this unless for some reason there is no reference to the original constructor, namely, no reference to Test.
Prototype chain
Prototype, __proto__, and constructor look like this:
Printing an instance of Test also validates the process shown on the diagram
Prototype may also have prototypes. Test.prototype inherits methods and properties from Object.prototype. This analogy, layer by layer, is called the prototype chain.
Scope of stereotype inheritance
We know that Object has many methods, such as object.key (), object.is (), etc., but we find that test does not inherit these methods. Why is this?
The reason is that methods or properties defined on prototype properties are inherited. That is, test instances inherit only methods on Object.prototype, not methods on Object.
The constructor itself is a function. How can you add a method to a function that is also an object type
So if we add attributes or methods to the Test function, the Test instance will not inherit, as in
Function Test() {} var Test = new Test() test.attr = 'attribute' console.log(test.attr) // Attribute console.log(test.attr) // undefinedCopy the code
conclusion
Above is my understanding of JS prototype and prototype chain, in-depth analysis of the relationship between prototype, __proto__, constructor, and analysis of the scope of prototype inheritance. If you feel helpful, please help to like + comment + favorites.
I’ll leave you with one last question:
Var num = 1 num.add(2) console.log(num)Copy the code