This article will introduce you to object prototypes and prototype chains in Javascript. There is a certain reference value, and friends in need can refer to it, and I hope it will be helpful to everyone.
Object prototype
I believe everyone has used map
like this:
let arr = [0, 1, 2] let doubleArr = arr. map(c => c * 2) console.log(doubleArr) // 0, 2, 4
I don’t know if you have thought about it, arr
itself does not set the map
attribute , then why can we use the map
function?
Print it out to see:
console.log(arr) // 0: 0 // 1: 1 // twenty two // length: 3 // __proto__: Array(0)
There is an object named __proto__
, if you expand it, you will see all the functions that can be used by Array objects; of course We can also find the map
function in it, and this is the arr.map
function called in the example:
console.log(arr.map === arr.__proto__.map) // true
The __proto__
object that appears here is the so-called Prototype.
Different from Java, C# and other class-based (Class) object-oriented languages, properties and methods are passed by defining classes, creating instances, specifying inheritance, etc.; Javascript is a Prototype-based pairing language, through the pre-established prototype object, when a new object is created, specify which prototype object the prototype of the object should refer to.
And when we call the property or method of the object, if the object itself does not have this property or method, Javascript will automatically find the method in its prototype, which is why we can directly call arr.map
without error.
Prototype chain
You may have found that in the previous example, the __proto__
object still has __proto__
property:
console.log(arr.__proto__) // Prototype of Array console.log(arr.__proto__.__proto__) // Prototype of Object console.log(arr.__proto__.__proto__.__proto__) // null
In the above mechanism, whenever an object is created, the prototype will be bound. Since the object has a prototype, the object prototype itself is also an object, naturally No exception; from this example we can see:
arr
is an array instance, the prototype is Arrayarr. __proto__
is the prototype of the array, the prototype is Objectarr.__proto__.__proto__
is the prototype of the object, the prototype isnull
arr.__proto__.__proto__.__proto__
is null, without any attributes
Because each object has a prototype, this forms an association , Layer-by-layer interdependent affiliation, we call them Prototype Chain (Prototype Chain); through this mechanism, objects can use the properties and methods in the prototype, and rely on the prototype chain layer by layer The sequential inheritance of layers allows objects to have the functions of all prototypes on the prototype chain. This is the operating mechanism behind Javascript objects.
Supplement: In Javascript, the end of almost every prototype chain will be Object, and finally point to
null
.
Using prototypes
Having said so much, it’s time for some code. Next, let’s practice the creation, setting and modification of prototypes.
Create a new object constructor first:
function Person(name) { this.name = name }Person.prototype.hello = function () { console.log(`Hello ${this.name}.`) }let gary = new Person('Gary') gary.hello() // Hello Gary.Object.getPrototypeOf(gary) // {hello: ƒ, constructor: ƒ}
The above example creates a simple object constructor Person( )
, and set object properties in the constructor. In the method of the object, because the method does not require each object to have its own copy to avoid redundant memory consumption, it should be like the previous Array.prototype.map
example. The method is set to the prototype object (Person.prototype
), so that objects created by this constructor can share these methods. Finally, create a new Person
object, and get the prototype of the newly generated object through getPrototypeOf(obj)
.
Q: Why not use
__proto__
to get the prototype object directly?
A: Because although__proto__
is supported by almost all browsers, it is a non-standard attribute; it is the correct way to get the prototype of the object throughgetPrototypeOf
.Reminder:
Person.prototype
is not the prototype ofPerson
, but the prototype of the new object created after the execution of the constructor; never put the constructor Theprototype
property of the object’s prototype is confused!
Prototype inheritance
Then create a new object prototype and inherit from Person
:
function Engineer(name, skill) { Person. call(this, name) this.skill = skill } Engineer.prototype = Object.create(Person.prototype) Engineer.prototype.cOnstructor= Engineerlet alice = new Engineer('Alice', 'Javascript') alice. hello() // Hello Alice. console.log(alice.skill) // JavascriptObject.getPrototypeOf(alice) // Person {constructor: ƒ}
The prototype of the new object Engineer
is established here, and through the specification of Engineer.prototype
, its Prototype inherits from Person.prototype
, and finally resets Engineer.prototype.constructor
to let the constructor point back to itself; thus, the most basic prototype inheritance is completed.
Q: Why do I need to reset
constructor
?
A:Object.create
has copied all the properties ofPerson.prototype
, and theconstructor
property will be overwritten , if theconstructor
attribute is wrong, the wrong result will be generated when makinginstanceof
judgment; therefore, when setting inheritance here, you need to recreateconstructor
again Assigned back to the constructor itself.
Modify the prototype
The reference and inheritance of the prototype are directly referred to the prototype object, not copying a prototype for each object; therefore, you can Using this feature, add custom properties and methods to the prototype, so that all objects of this type can get the new method; many Polyfills for older browsers are implemented in this way.
For example, when we were writing Vue projects, we may have done similar operations, putting highly common property methods into Vue.prototype
:
Object.defineProperty(Vue.prototype, '$date', { value: dateTimeFormat }) // then you can use it like this vm.$date(dateObj)
This is indeed very convenient, but we must also remind everyone that we must be careful when we are making prototype modifications. Following the previous example, if you try to modify the method in the Person
prototype:
Person.prototype.hello = function ( ) { console.log(`Bye ${this.name}.`) }gary. hello() // Bye Gary. alice.hello() // Bye Alice.
As shown in the result, when the object prototype is modified, all objects with this prototype on the prototype chain will be affected, regardless of whether the object is modified before It was created after modification.
It is recommended that unless it is a Polyfill, you should try your best to avoid modifying the prototype of the native object to prevent possible unexpected results.
ES6 Class
After reading the previous paragraph, do you feel tired? Don’t worry, the Class
syntax sugar has been added since ES6, which has greatly improved the developer experience. Let’s refactor the previous example with Class
:
class Person { constructor (name){ this.name = name } // The method will be automatically placed in Person.prototype hello() { console.log(`Hello ${this.name}.`) } }class Engineer extends Person { constructor (name, skill){ super(name) // call Person's constructor this.skill = skill } }let alice = new Engineer('Alice', 'Javascript') alice. hello() // Hello Alice. Object. getPrototypeOf(alice) // Person {constructor: ƒ}
It is very convenient. With the same function, the readability of the code has been improved a lot, and the cumbersome settings can be automatically completed by Grammar for you. However, behind the convenient syntax, the bottom layer is still the object prototype and the prototype chain.
Summary
The above is the description of the object prototype in Javascript. I hope it can help you understand the object prototype. In this language where everything is an object, Fully understanding and mastering object prototypes is one of the barriers that must be broken through to become a professional coder.
For more knowledge about programming, please visit: Programming Courses! !
The above is to understand the details of object prototype and prototype chain in Javascript. For more, please pay attention to other related articles on 1024programmer.com!