JS prototype and prototype chain diagram

A, prototype

In JavaScript, each prototype function has a property that points to the function prototype object.

E.g:

Copy the code
function Person(age) {
    this.age = age       
}
Person.prototype.name = 'kavin'
var person1 = new Person()
var person2 = new Person()
console.log(person1.name) //kavin
console.log(person2.name)  //kavin
Copy the code

The above example, prototype function points to an object, and create prototype instances when it is calling the constructor of this object, which is the prototype of person1 and person2.

Prototype concept: every javascript object creation (except null) and they will associated with another object, which is what we call prototype, each object will "inherit" the attributes from the prototype.

Let us express the relationship between the constructor and the instance with a prototype map:

Two, __ proto__

It is for each object (except null) would have for the property, called __proto__, this property will point to the object's prototype.

function Person() {

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

The diagram:

Additional information:

The vast majority of browsers support this non-standard way to access a prototype, but it does not exist in Person.prototype in fact, it comes from Object.prototype, not so much a property, as it is a getter / setter when using obj .__ proto__, it can be understood as the return Object.getPrototypeOf (obj).

Three, constructor

Each prototype has a constructor property, associated with the point to the constructor.

function Person() {

}
console.log(Person===Person.prototype.constructor)  //true

So then the next update graph:

Copy the code
the Person function () { 

} 

var = new new the Person Person (); 

the console.log (Person .__ proto__ == Person.prototype) to true // 
the console.log (== Person.prototype.constructor the Person) to true // 
// way to learn ES5 method, the object can be obtained prototype 
console.log (Object.getPrototypeOf (person) === Person.prototype ) // true
Copy the code

Additional information:

function Person() {

}
var person = new Person();
console.log(person.constructor === Person); // true

当获取 person.constructor 时,其实 person 中并没有 constructor 属性,当不能读取到constructor 属性时,会从 person 的原型也就是 Person.prototype 中读取,正好原型中有该属性,所以:

person.constructor === Person.prototype.constructor

 

四、实例与原型

 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

Copy the code
function Person() {

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) // Daisy

delete person.name;
console.log(person.name) // Kevin
Copy the code

在这个例子中,我们给实例对象 person 添加了 name 属性,当我们打印 person.name 的时候,结果自然为 Daisy。

但是当我们删除了 person 的 name 属性时,读取 person.name,从 person 对象中找不到 name 属性就会从 person 的原型也就是 person.__proto__ ,也就是 Person.prototype中查找,幸运的是我们找到了 name 属性,结果为 Kevin。

但是万一还没有找到呢?原型的原型又是什么呢?

五、原型的原型

 在前面,我们已经讲了原型也是一个对象,既然是对象,我们就可以用最原始的方式创建它,那就是:

var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin

其实原型对象就是通过 Object 构造函数生成的,结合之前所讲,实例的 __proto__ 指向构造函数的 prototype ,所以我们再更新下关系图:

 

六、原型链

 简单的回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。——摘自《javascript高级程序设计》

其实简单来说,就是上述四-五的过程。

继上述五中所说,那 Object.prototype 的原型呢?

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

引用阮一峰老师的 《undefined与null的区别》 就是:

null 表示“没有对象”,即该处不应该有值。

所以 Object.prototype.__proto__ 的值为 null 跟 Object.prototype 没有原型,其实表达了一个意思。

所以查找属性的时候查到 Object.prototype 就可以停止查找了。

最后一张关系图也可以更新为:

图中由相互关联的原型组成的链状结构就是原型链,也就是蓝色的这条线。

__proto__ 属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),再往上找就相当于在null上取值,会报错(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束,null为原型链的终点),由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。
  其实我们平时调用的字符串方法、数组方法、对象方法、函数方法等都是靠__proto__继承而来的

总结一下:

We need to bear in mind two things: ①__proto__ and the object constructor property is unique; ② prototype property is a unique function, because function is also an object, so also has the function __proto__ and constructor property.
__proto__ role attribute is that when accessing properties of an object, if the object is inside this property does not exist, then it will go to that object __proto__ attribute points (parent) where to find, been looking until _ null _proto__ end properties, and then further on to find the equivalent in the null value, it will complain. The object is connected via this link __proto__ property that is what we call the prototype chain.
role is to make the prototype property of function objects instantiated who can find common properties and methods that f1 .__ proto__ === Foo.prototype.
meaning constructor property is directed to the object constructor function, all functions (in this case as the subject) constructor final point Function.
  This concludes the article, I hope to help those students on the JS in the prototype, __ proto__ and constructor property has confused

Guess you like

Origin www.cnblogs.com/jayfeng/p/12163461.html