js the prototype and prototype chain

Constructor creates an object
function Person() {

    }
    let person1 = new Person()
    let person2 = new Person()
    person1.name = 'james'
    person2.name = 'kobe'
    console.log(person1);
    console.log(person2);

Let's create a person instance through new, we can see the different instances have their own attributes.

proto

We can see under each object will have attributes __proto__, this property will point to the object's prototype

    function Person() {

    }
    Person.prototype.name = 'chris'
    let person = new Person()
    let person1 = new Person()
    let person2 = new Person()
    person1.name = 'james'
    person2.name = 'kobe'
    console.log(person);
    console.log(person1);
    console.log(person2);


We will see the name attribute prototype of the next __proto__, then __proto__ prototype relationship with what is it?

prototype

Each function has prototype has a prototype property that we often used

Person.prototype.name = 'chris‘

So the question is, what is the prototype property of this function in the end point is it? Is the prototype of this function do?
In fact, prototype, prototype attribute points to a function object that it is calling the constructor created instance, is the prototype in this example person1 and person2 of.

What is it that the prototype? Can be understood: Every JavaScript object (except null) will be associated with another object when it is created, this object is what we call prototype, each object will inherit properties from the prototype called.

By comparing the prototype and constructor of __proto__ instance, we find that the relationship between the person and Person.prototype

person.__proto__ === Person.prototype  //true

Since the instance object and constructors can point to a prototype, so if there is a prototype property points to a constructor or instance of it?

constructor

Not difficult to find, each constructor has a constructor this property, we will find the console through the constructor property points to the associated constructor

So that we understand the relationship between constructor, an instance prototypes, and examples, then we talk about examples and prototypes relationship:

Under prototype examples

We know that if the property can not be read instance, will find the prototype associated with the object's attributes, if still finding out, went to prototype prototype, has been found so far top level.

    function Person() {

    }
    console.log(Person.prototype.name);   //underfind
    Person.prototype.name = 'chris';

    var person = new Person();

    person.name = 'james';
    console.log(person.name) // james 拿到实例的name属性

    delete person.name;
    console.log(person.name) // chris 拿到原型的name属性

But what if not read it? What next prototype prototype is it?

Under prototype prototype

通过上面的知识我们知道person.__proto__与Person.protype相等,那么Person.prototype.__proto__下又是什么呢?很显然就是对象实例的__proto__

    function Person() { }
    let person = new Person()
    let obj = new Object()
    console.log(Person.prototype.__proto__ === obj.__proto__)      //true
    console.log(Person.prototype.__proto__ === Object.prototype)   //true
    console.log(obj.__proto__.__proto__)                           //null

    let obj = new Object();
    obj.__proto__.name = 'chris'
    obj.name = 'Kevin'
    console.log(obj.name) // Kevin
    delete obj.name
    console.log(obj.name) // chris
原型链

既然我们知道Object的原型,那 Object.prototype的原型呢?

我们可以看到返回一个null,表达的就是已经没有原型了。
最终就是原型和原型链的结构

一些补充

关于 Funtion 中的原型 我们可以会发现 Function.prototype 有些特殊

Function.prototype === Function.__proto__  //true

这样看上去实例的原型和原型的原型是相等的,即是鸡也是蛋。 我们可以参考MDN关于__proto__的解释:

__proto__的读取器(getter)暴露了一个对象的内部  [[Prototype]] 。对于使用对象字面量创建的对象,这个值是  Object.prototype。对于使用数组字面量创建的对象,这个值是 Array.prototype。对于functions,这个值是Function.prototype。对于使用 new fun 创建的对象,其中fun是由js提供的内建构造器函数之一(ArrayBooleanDateNumberObjectString 等等),这个值总是fun.prototype。对于用js定义的其他js构造器函数创建的对象,这个值就是该构造器函数的prototype属性。

Object.__proto__ === Function.prototype              //true
Object.__proto__ === Function.__proto__             //true

引用冴羽的理解

至于为什么Function.__proto__ === Function.prototype,我认为有两种可能:一是为了保持与其他函数一致,二是就是表明一种关系而已。
简单的说,就是先有的Function,然后实现上把原型指向了Function.prototype,但是我们不能倒过来推测因为Function.__proto__ === Function.prototype,所以Function调用了自己生成了自己。

总结

1、实例对象的__proto__始终指向构造函数的prototype

2、只有构造函数才拥有prototype属性,对象(除了null)都拥有__proto__属性

3、每一个原型对象都有一个constructor属性指向它们的构造函数

4、要读取属性时,先读取实例上的属性,读取不到会在原型链上寻找相应属性

5、原型链按照__proto__的指向下一级对象

6、原型链的尽头始终是null

7、构造函数实例化以后,既是构造函数函数,也是对象

function Foo() {
}
const obj = new Foo()

Foo.prototype === obj.__proto__                          //true
obj.constructor === Foo                                        //true
Foo.prototype.__proto__ === Object.prototype   //true
Object.prototype.__proto__ === null                   //true
Object.constructor === Function                         //true

原文:https://juejin.im/post/5d0606286fb9a07ecb0ba713

Guess you like

Origin www.cnblogs.com/jessie-xian/p/11596113.html