Understand js prototype in 10 minutes

The prototype is so simple that you can figure it out in 10 minutes! ! !

function

Let’s first take a look at how we defined functions in ancient times. We directly use functionthe keyword to declare them.

function fun() {}

But sometimes we will find that functions are also defined in the following format

function Fun() {}

Except for the capitalization of the first letter of the second function name , there is essentially no difference between the two.

The meaning of capital letters in function names

When we need to use a function as a constructor , we usually capitalize the first letter of the function name to look more standardized, that’s all.

Instantiate

Using the keyword on the constructornew can create different instances (the essence of an instance is an object) , just like saying: you don’t have a girlfriend, but you can prepare a constructor new to have many girlfriends, that’s what it means!

Start building! !
  • Constructor (girlfriend constructor):
function GirlFriend() {}
  • Create the first gf1 (instance object)
const gf1 = new GirlFriend()

gf1. name = 'Xiao Mei' 
gf1. age = 18

console . log (gf1)   // {name: '小美', age: 18}
  • Create a second gf2 (instance object)
const gf2 = new GirlFriend()

gf2. name = 'Xiaoli' 
gf2. age = 19

console . log (gf2) // {name: '小丽', age: 19}

association

  • GirlFriendis a constructor
  • gf1and gf2are two instance objectsnew GirlFriend created by

So how to connect instance objects and constructors ?

  • There will be a property called by default on the instance object__proto__ , which is recorded here as the implicit prototype.
  • There will be a property called by default on the constructorprototype , which is recorded here as the display prototype

Usually what we call the prototype object refers here prototype. The attributes on the prototype objectconstructor can directly access the constructor (it is recommended to print it manually and observe it).
By default, the instance object points __proto__to the constructorprototype . If you want to access a certain The prototype object of the instance can be accessed through the following relationship

console.log(GirlFriend.prototype.constructor) // ƒ GirlFriend() {}
gf1.__proto__ === GirlFriend.prototype // true
gf2.__proto__ === GirlFriend.prototype // true

access

When I need to access a property that exists on an instance objectname , say :

console . log (gf1. name ) // 'Xiao Mei' 
console . log (gf2. name ) // 'Xiao Li'

When I need to access a property that doesn’t exist on the instance objectfeature , like :

console.log(gf1.feature) // undefined
console.log(gf2.feature) // undefined

Because there is no such attribute, it will naturally print. undefined
But if I want to add a common attribute to all instantiated objects , how should I handle it?

  • As explained above, by default, the implicit prototypes of instance objects created by the same constructor will point to the explicit prototype of the constructor , that is , so I only need to add it to this prototype.GirlFriend.prototype
GirlFriend.prototype.feature = 'beautiful'

At this time, access the properties on the instance again feature, and finally you can get normal printing.

console.log(gf1.feature) // beautiful
console.log(gf2.feature) // beautiful

What if I want to gf1add different ones to separately featureand visit again?

gf1.feature = 'pretty'

console.log(gf1.feature) // pretty
console.log(gf2.feature) // beautiful

But why can the properties I added to the display prototype be accessed directly through the instance object?

principle

  1. Each instance object created by the constructor is a brand new object , and we can add its own unique properties to the object.
  2. When we try to access a property on the instance object , if it exists, the value of the property will be returned directly; if it does not exist, the access will continue along the instance object , __proto__and if it is found, the value of the property will be returned. If not found, it will returnundefined

Notice

In order to understand the prototype more clearly, here we will mention a few more key points in js

Ordinary object – object
  • As long as it is an ordinary object object, it can be new Object()instantiated ( Object() is a built-in constructor ), that is to say, all object literals are Object()instances of
  • ObjectAs a constructor, Object.prototypeit points to a specific prototype object . As an instance of the object , its __proto__value is null, so Object.prototype.__proto__ = nullit reaches the end of the prototype when
const obj = {}
const obj1 = new Object()

console.log(obj.__proto__ === obj1.__proto__)  // true
console.log(obj1.__proto__ === Object.prototype) // true
console.log(Object.prototype.____proto__) // null

Going back to the above example, when I want to access the properties on the instance object : gf1

  • If the attribute exists, the corresponding value will be returned directly.
  • If the attribute does not exist, it will be gf1.__proto__searched along, essentially searching for GirlFriend.prototypethis object
    • If the attribute exists, the corresponding value will be returned directly.
    • If the attribute does not exist, then GirlFriend.prototypeas an Objectinstance object of itself also has __proto__the attribute, so it will be GirlFriend.prototype.__proto__searched along. Essentially, what is searched isObject.prototype
      • If the attribute exists, the corresponding value will be returned directly.
      • If it does not exist, it will search and search again Object.prototype.__proto__. At this time , Object.prototype.__proto__the value is null, and finally the attribute is not found and printsundefined

This order is easy to understand

  1. gf1.xx
  2. gf1.proto.xx
  3. gf1.proto.proto.xx
  4. gf1. proto . proto . proto .xx

When in the end __proto__neither nullis found, it will be printed. undefined
Therefore, __proto__the chain formed by accessing the object properties along is what is usually called the prototype chain.

Special object – function

  • functionIt is also a special type of object, so variables can be accessed directly through attributes.
  • The Function() constructor has been built-in , so all functions are counted as instance objectsFunction of
    • When Functionused as a constructor , its prototypeproperties can be accessed
    • When Functionused as an instance object , its __proto__properties can be accessed
// In Function here is: I instantiated and sent some 
console . log ( Function . __proto__ === Function . prototype ) // true 
console . log ( Function . prototype . constructor === Function ) // true
  • The built-in Object()is also a function, so Objectis also an instance objectFunction of my
console.log(Object.__proto__ === Function.prototype) // true