图解原型&原型链

82 阅读2分钟

在了解原型&原型链之前,一些前置知识要知道

  1. 普通函数、构造函数、和实例对象之间的关系。
  2. 函数的本质就是对象。

一、构造函数、普通函数和实例对象之间的关系,看代码:

//它只是一个普通的函数
const Animal = function(){

}

//Animal此时是构造函数
//dog是实例对象
const dog = new Animal();

这个例子说明了,Animal是普通函数

new Animal()是构造函数

new 出了个对象dog是实例对象

进入正题:

prototype__proto__、 constructor,这几个属性是什么,他们之间的关系。

这是一张原型关系图,我们一步一步把问题拆分去理解。

1.prototype

首先介绍的是prototype,它是函数独有的,我们可以在相关项目源码中经常看到他的身影,示例:

function Person() {

}

// prototype是函数才会有的属性
Animal.prototype.name = 'kiki';
var dog = new Animal();
console.log(dog.name) //kiki


所以我们可以从关系图中发现函数的prototype属性指向了一个对象, 这个对象就是实例原型

原型是什么:在JavaScript中原型是一个prototype对象,它从其他对象继承功能特性,用于表示类型之间的关系。

2.__ proto __

每一个对象(null除外),都有一个__proto__属性,这个属性会指向该对象的原型也就是实例原型

function Aminal() {

}
var dog = new Aminal();

// 证明 dog实例与构造函数都指向原型
console.log(dog.__proto__ === Aminal.prototype); // true

3.constructor

实例对象和构造函数都可以指向原型,那么原型可不可以指回去呢?

指回实例的没有,因为构造函数可以生成很多实例。

function Aminal() {

}
// 实例有很多
var dog = new Aminal();
var cat = new Aminal();
var duck = new Aminal();

指回构造函数的有,就是constructor属性,每一个原型都有一个constructor指回构造函数。

function Aminal() {

}
var dog = new Aminal();m

// 证明 dog实例与构造函数都指向原型
console.log(dog.__proto__ === Aminal.prototype); // 
true

// 证明原型可以指回构造函数
console.log(Aminal === Aminal.prototype.constructor); // true

// 注意:不是说实例没有constructor吗?
// 是的,但结果为true,是因为dog.__prop__指向的是原型,实际还是实例原型通过constructor指回构造函数
console.log(Aminal === dog.constructor); // true


image.png

原型的指向

我们已经讲了原型也是一个对象,既然是对象,就会存在__proto__属性。

Obejct()就是我们常见的初始化new出的对象。

var obj = new Object();

原型链

我们知道实例原型是一个对象,实例原型的原型的原型...最终的指向是什么?

是null;而我们熟知的instanceof用法就是沿着原型链找,如果属性不在原型链上,则会一直找,直到为null。

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

白色指向就是其原型链。

更新下图:

感谢观看 End!