ES里面没有真正的继承,可是能经过某些手段达到继承效果,从而让一个类拥有另一个类的方法 类 =>构造函数app
继承描述某语言环境---魔兽世界 哈!其实我没玩过 魔兽世界里面 有Humen类 Humen类里面有Gnome(侏儒) , gnome有方法say(个人名字)
有共有属性ggroup=gnome ,humen 有共有属性hgroup=humen , 有本身名字 hname 共有方法write();函数
总共共3种继承方式 一种类继承 一种是原型继承 还有一种组合继承 至于其余的继承方式,本质上没啥区别this
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的指向spa
另外附上某处偷来的,本身以为比较好的js世界里面的原型链图:prototype