ES里面没有真正的继承,但是能通过某些手段达到继承效果,从而让一个类拥有另外一个类的方法 类 =>构造函数
继承描述某语言环境---魔兽世界 哈!其实我没玩过 魔兽世界里面 有Humen类 Humen类里面有Gnome(侏儒) , gnome有方法say(我的名字)
有共有属性ggroup=gnome ,humen 有共有属性hgroup=humen , 有自己名字 hname 共有方法write();
总共共3种继承方式 一种类继承 一种是原型继承 还有一种组合继承 至于其他的继承方式,本质上没啥区别
function humen(name){ //人类类
this.name=name;
this.write=function(){
console.log("write")
}
}
humen.prototype.hgroup="humen";
new humen('张三');
//传统的是在gnome里面建立一个temp属性 指向humen构造函数,从而去用humen里面this指向ganme 然后去初始化gnome里面的属性和方法(略)
/**下面是类继承 */
function gnome(name){
this.say=function(){
console.log(this.name);
};
humen.call(this,name);
}
gnome.prototype.ggroup="gnome";
var gnome=new gnome("李四");
console.log(gnome.name); //"李四"
console.log(gnome.hgroup);//"underfined" 由此可以得出这种继承方式只是借用call 或者apply 来改变this 借用构造函数初始化属性和方法
//无法继承原型上面的属性和方法 /*************************下面是原型继承 ***********************/
function gnome(name){
this.name=name;
this.say=function(){
console.log(this.name);
}
}
gnome.prototype.ggroup="gnome";
gnome.prototype=new humen(); // 这里把一些公共的参数传进去。。。
var gnome=new gnome("李四");
gnome.say();//李四
console.log(gnome.hgroup); //humen 由此得出这种继承方式能够继承原型链上面的属性和方法 但是个体的方法(this.name)需要重新写一遍 /*************************都用的不爽 前面2种一种不能继承原型 一种构造函数里面的属性需要重新定义 混合继承***********************/
function gnome(name){
this.say=function(){ //自己的方法
console.log(this.name);
};
humen.call(this,name);
}
gnome.prototype=new humen(); //new humen里面name属性是undefined 被类继承的name覆盖
gnome.prototype.ggroup="gnome";
var gnome1=new gnome("李四");
gnome1.say();//李四
gnome.prototype.constructor=gnome; //由于用原型继承 构造函数方向指向humen
console.log(gnome1.hgroup);//"humen"
console.log(gnome1.ggroup); //"gnome"
总结:每使用new 关键字new一个对象都是在创建一个空对象,改变this指针指向空对象,然后初始化其中属性和方法,还有_proto_指向原型对象,所以对于一些公用的属性和方法定义在原型对象之中,避免浪费内存,私有的(与参数相关)则放在构造函数中。类继承和原型继承都有各自的弊端,组合继承则互补,实现完美继承,注意constructor的指向
另外附上某处偷来的,自己觉得比较好的js世界里面的原型链图: