Home  >  Article  >  Web Front-end  >  Take you to explain the JS prototype chain in detail

Take you to explain the JS prototype chain in detail

不言
不言forward
2018-10-19 14:53:553090browse

The content of this article is about explaining the JS prototype chain in detail. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

My understanding of js prototypes and prototype chains has always been confusing. After reading "JavaScript Advanced Programming" and various articles, I finally have a preliminary understanding of prototypes and prototype chains. Although I still don’t have a deep understanding, I will analyze a question I encountered some time ago and use my own ideas to interpret it to deepen my understanding of prototypes and prototype chains.

1. Question

What is the result of running the following program?

function Animal() {
    this.name = 'Animal';
}

Animal.prototype.changeName = function (name) {
    this.name = name;
}

function Cat() {
    this.name = 'Cat';
}

var animal = new Animal();

Cat.prototype = animal;
Cat.prototype.constructor = Cat;

var cat = new Cat();

animal.changeName('Tiger');

console.log(cat.name)

A. Animal
B. Cat
C. Tiger
D. None

The answer isB Cat

2. Interpretation

1. Prototype object

Whenever a new function is created, a prototype attribute will be created for the function according to a specific set of rules. This property points to the function's prototype object. By default, all prototype objects automatically get a constructor attribute, which is a pointer to the function where the prototype attribute is located.
The following diagram is used to illustrate
function Animal() {
    this.name = 'Animal';
}
Animal.prototype.changeName = function (name) {
    this.name = name;
}

Take you to explain the JS prototype chain in detail

First, an Animal function is created. Animal contains a prototype attribute, pointing to Animal Prototype, and Animal.prototype. constructor points to Animal. At this time, because the name attribute is defined in the function, it is not in the Animal Prototype, and the changeName function is defined through Animal.prototype.changeName, so we can use this method to share the prototype when instantiating multiple objects. Save method.
Similarly, the same is true when the Cat function is created.

function Cat() {
    this.name = 'Cat';
}

Take you to explain the JS prototype chain in detail

2. Create an instance

When the constructor is called to create a new instance, the instance will contain a pointer internally (internal property), pointing to the prototype object of the constructor. This pointer is called [[Prototype]] in ECMA-262 5th edition. Although there is no standard way to access [[Prototype]] in scripts, Firefox, Safari, and Chrome support an attribute __proto__ on every object. It is important to note that this connection exists between the instance and the constructor's prototype object, not between the instance and the constructor.

Take you to explain the JS prototype chain in detail

// 将Cat的原型对象指向animal实例,获得animal中的属性,原有的属性丢失
Cat.prototype = animal;

Take you to explain the JS prototype chain in detail

This part is equivalent to pointing the pointer of Cat’s prototype object to animal instance, so the original constructor attribute in the Cat prototype object is lost and replaced by the attributes in the animal instance, including the name attribute and the __proto__ internal attribute. At the same time, the __proto__ attribute also points to Animal.prototype, so Cat can also pass the prototype Chain searches for properties and methods called to Animal.

// 相当于重新创建了constructor,指向Cat构造函数
Cat.prototype.constructor = Cat;

Take you to explain the JS prototype chain in detail

This part is equivalent to re-creating a constructor attribute in the prototype object and pointing to the Cat constructor.

var cat = new Cat();   // 实例化一个Cat对象,跟实例化Animal相似

Take you to explain the JS prototype chain in detail

3. Call the method

animal.changeName('Tiger');

When var animal = new Animal(); instantiates an Animal object, Animal contains an internal property that points to Animal.prototype; in other words, animal has no direct relationship with the constructor Animal. However, you can see that although changeName is not included in the instance, we can call animal.changeName(name). This is achieved through the process of finding the object attributes, that is:

First find the instance in the instance Whether there is a changeName method in animal, if not, continue to search, go to Animal.prototype to find if there is a changeName method, if so, call it, if not, continue to search, search in Object.prototype, if it is not found in the end, a null will be returned.

Obviously, there is no changeName method in the instance animal here, so you need to go to Animal.prototype to find the changeName method, and call it to successfully modify the name attribute in the instance animal to Tiger.

At this time, since Cat.prototype points to the instance animal, the name attribute in Cat.prototype also changes to Tiger.

Take you to explain the JS prototype chain in detail

console.log(cat.name)  // Cat

最后,获取cat.name,与查找方法同样,也是先去实例中cat查找是否含有name属性,在这里很明显是存在的,因此直接结束寻找,此时cat.name = 'Cat'。

三、总结

通过这道题,加深了我对原型和原型链的理解,其实这道题也可以扩展到关于继承的知识点,在JavaScript中实现继承主要是依靠原型链来实现。

The above is the detailed content of Take you to explain the JS prototype chain in detail. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete