思维导图:
1 原型、原型链、构造函数三者的关系
简单的可以用以下这张图表示(清晰明白)
这里有一个易错点
当修改了 prototype 一定要重新写上构造函数
function Foo() {
this.a = 1
}
Foo.prototype = {
aa: 10,
bb: function() {
console.log(20);
},
constructor: Foo //千万别忘
}
let f = new Foo()
console.log(f.a);
console.log(f.aa);
f.bb()
复制代码
或者是这种修改方式 Foo.prototype.color = 'blue'
2 原型链的继承方式
实例对象 ==》可以拿到 原型上的属性方法, ==》原型的原型的属性方法
整个原型链的属性方法都可以拿到
//对象继承 原型链方式
function Super(){
this.a = '111';
}
Super.prototype.say = function() {
console.log('222');
}
function Sub(){
}
//Sub继承Super
Sub.prototype = new Super()
let sub1 = new Sub();
console.log(sub1.a); // 111
sub1.say() // 222
复制代码
这种继承的问题:实例修改导致原型上的属性,方法的变动
this.a = [1,2,3,4]
let sub1 = new Sub()
let sub2 = new Sub()
sub1.a.push(5)
// a被修改了 ==>
// sub1.a [1,2,3,4,5]
// sub2.a [1,2,3,4,5]
复制代码
问题:引用值共享的问题
3 构造函数继承
为了解决上面原型链继承导致的引用值共享问题
// 构造函数继承
function Super() {
this.a = [1,2,3,4];
}
Super.prototype.say = function() {
console.log(222);
}
function Sub() {
Super.call(this);
}
let sub1 = new Sub();
let sub2 = new Sub();
sub1.a.push(5)
console.log(sub1.a); //1, 2, 3, 4, 5
console.log(sub2.a);// 1, 2, 3, 4
复制代码
那他的问题呢?
无法调用函数了==》why, 修改了 this 指向的是sub, 不指向原型了
问题:没办法拿到原型上的方法
4 组合继承
结合以上两者,组合继承 ==》 伪经典继承
// 组合继承
function Super() {
this.a = [1,2,3,4];
}
Super.prototype.say = function() {
console.log(222);
}
//借用构造函数继承
function Sub() {
Super.call(this);
}
//原型链继承
Sub.prototype = new Super();
let sub1 = new Sub();
let sub2 = new Sub();
sub1.a.push(5)
console.log(sub1.a); //1, 2, 3, 4, 5
console.log(sub2.a);// 1, 2, 3, 4
sub1.say() // 222
复制代码
小问题:执行了两次 Super
5 寄生组合继承
经典继承
function Sub() {
Super.call(this);
}
//原型链继承
// Sub.prototype = new Super();
Sub.prototype = Object.create(Super.prototype)
let sub1 = new Sub();
let sub2 = new Sub();
sub1.a.push(5)
console.log(sub1.a); //1, 2, 3, 4, 5
console.log(sub2.a);// 1, 2, 3, 4
sub1.say() // 222
复制代码
还是有问题!!!
Sub.prototype.subSay = xxx
被重写了,就会有问题
6 es6继承
解决上面的问题
class Super{
}
class Sub extends Super{
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END