类的声明与实例化,继承
// 类的声明
function Animal(){
this.name = 'name';
}
// ES6中class的声明
class Animal2(){
constructor(){
this.name = 'name';
}
}
console.log(new Animal(),new Animal2());
继承的方法:
// 方法一:借助构造函数实现继承
function Parent1(){
this.name = 'parent1'
}
function Child1(){
Parent1.call(this);
this.type = 'child1';
}
console.log(new Child1());
//方法二:借助原型链继承
function Parent2(){
this.name = 'parent2';
this.play = [1,2,3];
}
function Child2(){
this.type = 'child2';
}
Child2.prototype = new Parent2();
console.log(new Child2());
var s1 = new Child2();
var s2 = new Child2();
console.log(s1.play,s2.play);
s1.play.push(4);
console.log(s1.play,s2.play);
//组合方式继承
function Parent3(){
this.name = 'parent3';
}
function Child3(){
Parent3.call(this);
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
借助构造函数继承,能继承内部的属性,但是无法继承对象的prototype;
而使用原型链继承,则不但可以继承内部属性,还可以继承对象的protptype,但是需要注意的是,需要Child2.proto.name才可以。这种方法有个缺点,当我们实例化2个,改变其中一个时,另一个也随之改变;
使用第三组方法,组合继承,则不会出现第二种方法的问题。同时也会出现一个问题,那就是Parent3执行了2次,其实是完全没有必要的,我们可以对这种组合继承方式做一个优化,方法如下:
//组合方式继承优化
function Parent4(){
this.name = 'parent4';
this.play = [1,2,3];
}
function Child4(){
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype;
var s5 = new Child4();
var s6 = new Child4();
console.log(s5,s6);
console.log(s5 instanceof Child4,s5 instanceof Parent4);
console.log(s5.constructor);
打印输出后的结果则为:解决了上一个问题,同时会发现使用constructor发现指向了Parent4,而不是我们想要的Child4;
优化方案二:
//组合方式继承优化2
function Parent5(){
this.name = 'parent5';
this.play = [1,2,3];
}
function Child5(){
Parent5.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype);
Child5.prototype.constructor = Childe5;
var s7 = new Child5();
console.log(s7 instanceof Child5);
console.log(s7.constructor);
使用这种方法完美的完成了任务,这中间涉及了很多原型链的知识和理解;