目标
了解原型链和原型对象
js实现各种方式的继承
知识要点
constructor
构造器,当创建对象时会在原型中拥有一个constructor,constructor指向构造函数本身
原型链
js中所有皆为对象
对象中会有__proto__原型链属性,原型链指向构造函数中的prototype原型
函数中除了__proto__原型链属性,还会有prototype原型
function Foo(){}
var foo = new Foo()
foo.__proto__ === Foo.prototype; // true
Foo.prototype.constructor === Foo; // true
Foo.__proto__ === Function.prototype; // true
Function.__proto__ === Object.prototype; // true
Object.__proto__ === Function.prototype; // true
Object.prototype.__proto__ === null; //true
Foo.prototype.__proto__ === Object.prototype; // true
继承(各种继承方式的优缺点)
原型链继承
function Father() {
this.name = 'father';
}
Father.prototype.say = function() {
alert('father func')
}
function Child(){}
Child.prototype = new Father();
Child.prototype.constructor = Child;
缺点:
- 子类共享了父类的属性
- 实例化时无法向父类传参
构造函数继承
function Father() {
this.name = 'father';
}
Father.prototype.say = function() {
alert('father func')
}
function Child(){
Father.apply(this, Array.from(arguments))
}
优点:
- 解决了属性共享的问题
- 可以给父类传参
缺点:
无法获取prototype方法
组合继承
function Father() {
this.name = 'father';
}
Father.prototype.say = function() {
alert('father func')
}
function Child() {
Father.apply(this, Array.from(arguments))
}
Child.prototype = new Father();
Child.prototype.constructor = Child;
优点:
- 解决了属性共享的问题
- 可以给父类传参
- 可以获取prototype方法
缺点:
会调用两次构造函数
寄生组合继承
function Father() {
this.name = 'father';
}
Father.prototype.say = function() {
alert('father func')
}
function Child() {
Father.apply(this, Array.from(arguments))
}
Child.prototype = Object.create(Father.prototype);
Child.prototype.constructor = Child;
优点:解决了以上问题
多重继承
function Father() {
this.name = 'father';
}
Father.prototype.say = function() {
alert('father func')
}
function Child() {
Father.apply(this, Array.from(arguments))
}
function OtherChild() {
this.name = 'otherChild';
}
OtherChild.prototype.getName = function() {
return this.name;
}
Child.prototype = Object.create(Father.prototype);
Object.assign(Child.prototype, OtherChild.prototype);
Child.prototype.constructor = Child;