JS——原型和原型链、面向对象
1 知识点
1.2.1 类与实例
- 类的声明
1)ES5
Function Animal( ) {
this.name = 'name';
}
2)ES6中class的声明
class Animal2( ) {
constructor( ) {
this.name = 'name';
}
}
- 生成实例
1)new Animal( );
2)new Animal2( );
1.2.2 类与继承
继承有几种方式?各有什么优缺点?
- ① 借助构造函数法(call、apply)
function Child() { Parent.call(this) }
function Parent1( ) {
this.name = 'name1';
};
Parent1.prototype.say = function( ){
};
function Child1( ) {
Parent1.call(this);
this.type = 'child1';
};
console.log(new Child1( ).say( )); //undefined
优点:简单;
缺点:call 回调的 this 指向父函数里的内容,没有指向父元素的原型。
- ② 借助原型链
Child.prototype = new Parent()
function Parent2( ) {
this.name = 'name2';
this.play = [1,2,3];
};
function Child2( ) {
this.type = 'child2';
};
Child2.prototype = new Parent2( );
var s1 = new Child2( );
var s2 = new Child2( );
s1.play.push(4);
console.log(s1.play; s2.play) // [1,2,3,4], [1,2,3,4]
优点:解决局部继承的情况,指向父函数的原型;
缺点:new子类的实例的原型是共用的;
- ③ 组合(构造函数+原型链)
function Child() { Parent.call(this) }
Child.prototype = new Parent()
function Parent3( ) {
this.name = 'name3';
this.play = [1,2,3];
};
function Child3( ) {
Parent3.call(this);
this.type = 'child3';
};
Child3.prototype = new Parent3( );
var s3 = new Child3( );
var s4 = new Child3( );
s3.play.push(4);
console.log(s3.play; s4.play) // [1,2,3,4], [1,2,3]
优点:解决构造函数法局部继承、借助原型链法new实例的原型共用的问题;
缺点:每次new实例都会重复调用父函数;
- ④ 优化1(原型式继承)
function Child() { Parent.call(this) }
Child.prototype = Parent.prototype
function Parent4( ) {
this.name = 'name4';
};
function Child4( ) {
Parent4.call(this);
this.type = 'child4';
};
Child4.prototype = Parent4.prototype;
var s5 = new Child4( );
console.log(s5 instanceof Child4) // true
console.log(s5.constructor) // Parent4
优点:将父函数prototype直接赋值给子函数的prototype,每次new实例不需重复执行父函数;
缺点:子函数的实例的constructor指向父函数
- ⑤ 优化2(寄生组合式)
function Child() { Parent.call(this) }
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
function Parent5( ) {
this.name = 'name5';
};
function Child5( ) {
Parent5.call(this);
this.type = 'child5';
};
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Child5;
var s6 = new Child5( );
console.log(s6 instanceof Child5) // true
console.log(s6.constructor) // Child5
优点:
通过 Object.create 的方法新建父函数prototype 赋值给 子函数prototype,
并将子函数prototype的 constructor 指向子函数本身,
解决了子函数实例的 constructor 指向父函数的问题;
2 问答
题目:
*继承的方式有哪些?有什么优缺点?