JS 原型,原型链

86 阅读2分钟

image.png

图片传达一个思想:每个构造函数都有一个原型对象,原型有一个属性指向构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例,那么这个原型本身有一个内部指针指向另一个原型,相应的另一个二元性也有一个指针指向另一个构造函数,这样在实例和原型中间就有了一条原型链。

重点:以对象字面量方式创建原型方法会破坏之前的原型链,这相当于重写与原型链。

为什么有原型,原型链?

通过原型链可以访问原型链上的其他原型的属性和函数。

原型模式继承

基本思想:通过原型继承多个引用类型的属性和方法。

优点:可以访问原型链上的其他原型的属性和函数。

问题:

一:通过原型链继承后,原型中包含的引用值会在所有实例中共享。

function Fun(){
  this.pets = ['dog','cat'];
}

let f1 = new Fun();
let f2 = new Fun();

每个构造函数的实例都会有自己的pets属性,包含自己的数组,两者不会影响。

function SubFun(){}
SubFun.prototype = new Fun();

let sub1 = new SubFun();
sub1.pets.push('duck')
let sub2 = new SubFun();
sub2.pets.push('bird');

console.log(f1)
console.log(f2)
console.log(sub1.pets)
console.log(sub2.pets)

结果:

其中我们打印sub1和sub2时 结果是 Fun {} 因为这个属性在Fun中。

二:子类型在实例化不能给父类型传参。

原因是:不能在不影响所有对象实例的情况下把参数传进父类的构造函数。

基于这两点目前不会被单独使用。

与OOP中的类的区别

类:创建对象实例时,会把对象中的方法和属性复制一份到实例中。

js:在对象实例和构造器之间构建一个链接(是__proto__属性,从构造函数prototype属性派生的)

关联知识: new 手写原理