再来理一理原型 、原型对象、__proto__之间的关系

经过一个例子来聊今天的内容:bash

function Fun(){}
Fun.prototype.age = 18;

var f = new Fun();
console.log(f.age) // 18;
console.log(Fun.age) // undefined
复制代码

为何f.age的结果是18,而Fun.age的结果是undefined?函数

在开始以前,咱们先了解一下原型 、原型对象、__ proto__ 这三个概念。spa

基本概念

原型(prototype):是指函数内部的一个属性,这个属性是个指针,指向原型对象。prototype

原型对象(prototype object):是指函数内部的一个对象,这个对象包含属性和方法是共享的。指针

__ proto__([[prototype]]):是实例对象内部的一个属性,它指向当前函数/Object类型的原型对象。code

它们之间的关系是:cdn

image

prototype属性 和 __proto __的注意点

有两个注意点:对象

  1. 单纯的对象只有__proto__属性,没有prototype属性
  2. 函数对象有__proto__ 和prototype属性
    image

原型、原型对象、__ proto __、原型链的关系

它们之间的关系,咱们经过下面的图来了解。 blog

image

经过上面的图得出一些结论:原型链

  1. 全部的原型对象,都有constructor属性,指向这个实例的构造函数;

  2. 函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而建立的原型对象

  3. __proto__指向原型链上一个节点的原型;

  4. 咱们所说的往原型链查找属性或方法,是指"沿着.__proto __属性找,而不是"沿着.prototype这个属性去查找;

  5. __ proto__ 和prototype是彻底不一样的两个东西; obj. __proto __ === 函数.prototype; 仅仅是说明,它们共同指向原型对象,仅此而已;

  6. 实例.__ proto__ 是构造函数.prototype,构造函数原型对象.__ proto__ 是Object.prototype;即:

obj.__ proto__  === Fn.prototype
    obj.__ proto__.__proto__ === Fn.prototype.__proto__ === Object.prototype
复制代码

函数.__ proto__ 是Function.prototype,Object类型. __proto __ 是Function.prototype;即:

Fn.__proto__ === Function.prototype
    Object.__proto__ === Function.prototype
复制代码

Function类型. __proto__是其自己;即:

Function.__ proto __ === Function.prototype
复制代码
  1. 原型链的顶端是null。

回到最初的问题

咱们再回头看这个例子:

function Fun(){}
Fun.prototype.age = 18;

var f = new Fun();
console.log(f.age) // 18;
console.log(Fun.age) // undefined
复制代码

为何f.age的结果是18,而Fun.age的结果是undefined?

f.age:

由于,f是一个实例对象,f.age没有值,则会往者f上一个节点的原型,f. __ proto __属性找,

从上图看是 Fun.prototype(注意,这是一个原型对象,而不是构造函数的prototype属性==)

因此找到的结果是18。

Fun.age:

由于Fun是一个函数,这个函数上没有定义.age属性,(注意:Fun.prototype上的属性 != Fun的属性==),那这个时候,就会往Fun.__proto__属性上找,

从上图看是Function.protype(原型对象),也没有找到,再往上找,直到顶端,而后返回undefined。

这回能明白上面的结果了吗?

相关文章
相关标签/搜索