我们以工厂生产产品为例来聊聊 js 中的原型
-
首先,我们有一个构造函数
Productfunction Product(p){ this.p = p }它就相当于一个生产机器,能够产出各种产品(实例)
-
我们可以通过
let product = new Product(p)来创建一个实例,这个过程相当于生产了一件产品,这个实例就是产品
-
机器(构造函数)生产产品,那必须有个模板样品,这个模板样品,就是这个构造函数的
prototype,也就是原型对象,每一次实例化一个对象,都是根据构造函数的这个prototype为模板创建一个实例对象 -
创建出来了实例对象
product,在大部分浏览器里,它都会有一个对象__proto__,这个对象就是product的构造函数的prototype(生产这个 product 的机器所使用的模板样品) -
综上,我们可以知道构造函数有
prototype属性, 指向构造函数所使用的原型对象,而构造函数new出来的实例有__proto__属性,指向这个实例的原型。实例的 原型__proto__同时也是构造函数所使用的原型对象prototype
关于对象的原型和原型链
我们来看一个类
class SonClass{
constructor( pro ){
this.pro = pro
}
Intro(){
console.log(" I am SonClass ")
}
}
- 实际上,类的本质是一个构造函数,或者说,类指向了一个构造函数,所以通过类去创建实例对象,本质仍然是通过构造函数去创建实例对象,此时,类的
prototype属性,实际上就是构造函数的prototype属性,通过这个类new出来的实例对象的__proto__等于这个类的prototype - 值得注意的是,用一个类去构造一个实例时,这个实例的原型(也就是
__proto__)不是这个类本身,而是这个类的原型对象(prototype)
对象继承中的原型和原型链
class FatherClass{
constructor(fatherpro){
this.fatherpro = fatherpro
}
static function FatherFunc(){
console.log("Here is a static function from FatherClass")
}
}
class SonClass extends FatherClass{
constructor(fatherPro,sonPro){
super(fatherPro)
this.sonPro = sonPro
}
}
要了解对象继承中的原型和原型链,我们首先要了解,类实际上也是一个对象,其次,我们要知道,类继承的机制是什么,我们以一个例子来说明,SonClass 继承自 FatherClass的过程,相当于以下两行代码
Object.setPrototypeOf(SonClass.prototype, Father.prototype)
Object.setPrototypeOf(SonClass, FatherClass)
- 我们先大致了解
Object.setPrototypeOf方法,直白地讲,假设参数为两个对象(obj1,obj2),那该函数让obj1.__proto__ = obj2,接着,我们分别来聊聊这两行代码 - 第一行代码,我们把
SonClass和FatherClass两个类,看作两个构造函数(正如前文所说,类实际上是指向构造函数的),经过这一行代码,SonClass的原型对象prototype的__proto__,等于了FatherClass的原型对象prototype,所以SonClass.prototype.__proto__ === FatherClass.prototype的返回结果是true - 第二行代码,我们把
SonClass和FatherClass两个类,看作两个对象(类实际上也是对象),经过这一行代码,SonClass成功继承了FatherClass的静态属性,SonClass.__proto__ === FatherClass的返回结果也是true最后,我们回到生产车间 - 我们把
FatherClass比作一台生产玩具汽车的机器,把SonClass比作一台生产超级玩具汽车的机器,它们都是类,也是构造函数,还是对象 SonClass这台机器,是以FatherClass这台机器为样品去创建出来的(这时我们把两台机器都看作对象),那么显然有SonClass.__proto__ === FatherClass的结果为true- 其次呢,
SonClass这台机器生产过程中所使用的样品,也是根据FatherClass这台机器生产过程中所使用的样品为样品去创建出来的(这时我们把两台机器看作构造函数),也就是说FatherClass的产品(FatherClass.prototype)是SonClass的产品样品的样品(SonClass.prototype.__proto__),也就是说超级玩具汽车样品是以超级汽车的样品作为样品去创造出来的,显然有SonClass.prototype.__proto__ === FatherClass.prototype