一、对比–对象原型继承(又称 原型链继承)
-
对象原型继承的关键语句:Suber.prototype = new Super();
-
存在的问题:引用值共享(无论是this对象 还是prototype对象上的引用值);
-
构造函数继承:解决了 this对象上引用值共享的问题!
二、构造函数继承 的实现
- 特点:构造函数继承,继承的是原型的 this 对象,没有继承prototype对象。
//构造函数继承
function Super() {
this.pbrand = 'super';
// 添加引用值
this.a = [1, 2, 3, 4, 5];
}
function Suber() {
this.bbrand = 'suber';
//构造函数继承
Super.call(this);
}
let suber1 = new Suber();
let suber2 = new Suber();
suber1.pbrand = 'new super';
console.log(suber1.pbrand); //new super
//没有继承prototype对象
console.log(suber1.__proto__.pbrand); //undefined
console.log(suber2.__proto__.pbrand); //undefined
- 构造函数继承的关键语句: Super.call(this);
三、Super.call(this)
function Suber() {
this.bbrand = 'suber';
//构造函数继承
Super.call(this);
}
let suber1 = new Suber();
-
首先、在 new Suber() 实例化过程中,this 对象指向 实例对象 suber1;
-
在 new Suber() 实例化过程执行代码:Super.call(this); , 相当于Super.call(suber1);
执行Super.call(this)相当于suber1.pbrand = ‘super’; …因此原型上的属性(this对象)为每个实例对象私有,
所以实例之间(suber1 /suber2)互不影响。
四、验证一下引用值不共享,
//构造函数继承
function Super() {
this.pbrand = 'super';
// 添加引用值
this.a = [1, 2, 3, 4, 5];
}
function Suber() {
this.bbrand = 'suber';
//构造函数继承
Super.call(this);
}
let suber1 = new Suber();
let suber2 = new Suber();
suber1.a.push(8);
console.log(suber1.a); //[1, 2, 3, 4, 5, 8]
console.log(suber2.a); //[1, 2, 3, 4, 5]
五、缺点
-
prototype上的属性没有继承到
-
并且不知道继承的是哪个对象,所以一般在构造函数继承中还会添加一条语句:
//构造函数继承
function Super() {
this.pbrand = ‘super’;
// 添加引用值
this.a = [1, 2, 3, 4, 5];
}
function Suber() {
this.bbrand = ‘suber’;
//构造函数继承
Super.call(this);
}
Suber.prototype = Super; //缺点,容易被后面定义Suber.prototype的属性覆盖,所以有了下局
Suber.prototype.super = Super; //为了开发人员查看到它的父亲是谁,属性名随你自己命名