三分钟极速版了解JavaScript原型原型链
2024-04-10 02:50:23  阅读数 570

简介

看完很快,稍加思索还得一会哈哈
什么是原型

每个函数都会创建一个 prototype 属性,这个属性是一个对象。而这个对象就是通过调用构造函数创建的对象的原型。

为什么要使用原型
使用原型对象的好处是,在它上面定义的属性和方法可以被对象实例共享。

//例如
function Person() {} 
Person.prototype.name = "Nicholas";

let person1 = new Person(); 
person1.sayName(); // "Nicholas" 

1.构造函数+原型对象的关系

注意的是,我们的Person是构造函数(函数)。而Person.prototype是原型对象(对象)。所谓原型就是通过函数的prototype属性来获取原型对象。

构造函数.prototype -> 原型对象

所有原型对象自动获得一个名为 constructor 的属性,指回与之关联的构造函数。所以可以得到关系

原型对象.constructor => 构造函数

image.png

2.实例+构造函数+原型的关系

首先我们要明白构造函数、原型对象和实例是 3 个完全不同的对象。实例与构造函数原型之间有直接的联系,但实例与构造函数之间没有:如下所示

 person1 = new Person(), 
 person2 = new Person(); 
/** 
 * 构造函数、原型对象和实例
 * 是 3 个完全不同的对象:
 */ 
console.log(person1 !== Person); // true 
console.log(person1 !== Person.prototype); // true 
console.log(Person.prototype !== Person); // true 

每次调用构造函数创建一个新实例,这个实例的内部[[Prototype]]指针就会被赋值为构造函数的原型对象。
但 Firefox、Safari 和 Chrome会在每个对象上暴露__proto__属性,通过这个属性可以访问对象的原型。

实例对象通过这个可以直接指向原型对象,如下

/** 
 * 实例通过__proto__链接到原型对象,
 * 它实际上指向隐藏特性[[Prototype]] 
 * 
 * 构造函数通过 prototype 属性链接到原型对象
 * 
 * 实例与构造函数没有直接联系,与原型对象有直接联系
 */ 
console.log(person1.__proto__ === Person.prototype); // true 
conosle.log(person1.__proto__.constructor === Person); // true 

可以观察到实例对象person1通过__proto__可以得到原型对象,然后通过原型对象的constructor属性又可以得到构造函数。

实例对象.__proto__ -> 原型对象

image.png

原型的原型以及与object的关系

在前面,我们已经讲了原型对象也是一个对象,既然是对象,我们知道object是个祖宗类。所以我们原型对象__proto__属性指向的就是object的原型对象object.prototype

原型对象.proto -> object.prototype

/** 
* 正常的原型链都会终止于 Object 的原型对象
* 补充一点,Object 原型的原型是 null 
*/ 
console.log(Person.prototype.__proto__ === Object.prototype); // true 
console.log(Person.prototype.__proto__.constructor === Object); // true 
console.log(Person.prototype.__proto__.__proto__ === null); // true
image.png