在《关于JavaScript中的继承(一):类式继承》 中已经基本上实现了类式继承,但仍然还存在一些问题,接下来对之前的实现进一步进行完善。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var  Parent = function  (name)    this .name = name || 'heroic' ; }; Parent.prototype.print = function  ()     console .log('name: ' , this .name); }; var  parent = new  Parent();var  Child = function  (name)    Parent.apply(this , arguments ); }; Child.prototype = parent; Child.prototype.setChildAge = function  (age)     this .age = age; }; parent.setChildAge(10 ); console .log(parent.age);  
正如代码所见,在为子对象原型添加自己独有方法的时候,父对象也受到了影响,这可不是期望的结果。  
1 2 3 4 5 var  child = new  Child('child' );console .log(child.name);  delete  child.name;console .log(child.name);  
同样如代码所示,child对象持有了两个name属性,一个是通过构造函数拷贝的,另一个是原型链上的,当删除掉本身的name属性后,便访问到了原型链上的了。对于这个问题,解决方案很简单直接:  
1 2 3 4 5 Child.prototype = Parent.prototype;   delete  child.name;console .log(child.name);  
但是这种方法也并没有解决最开始的那个问题,即添加或删除子对象原型上的属性时,会一并反映到父对象中。这个时候就需要用到《关于JavaScript中的继承(二):原型式继承》 中用到的临时构造函数了。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var  inherit = function  (subClass, superClass)    var  F = function  ()     F.prototype = superClass.prototype;   subClass.prototype = new  F; }; inherit(Child, Parent); Child.prototype.setChildAge = function  (age)     this .age = age; }; parent.setChildAge(10 );   
不再影响父对象的行为了,而且还可以为inherit方法增加子对象访问父对象行为的特性。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var  inherit = function  (subClass, superClass)    var  F = function  ()     F.prototype = superClass.prototype;   subClass.prototype = new  F;   subClass.prototype._super = superClass.prototype; }; Child.prototype.print = function  ()     console .log('before print...balabala...' );   this ._super.print.call(this ); }; var  child = new  Child('child' );child.print();                    
最后,如果说这个类式继承模式还有哪点不够完美的话,那就是在子对象继承父对象之后,子对象的构造函数指向被改写了。  
1 console .log(child.constructor === Parent);  
没办法,只有在继承的最后,把constructor修正回来就是。  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var  inherit = function  ()    var  F = function  ()     return  function  (subClass, superClass)       F.prototype = superClass.prototype;     subClass.prototype = new  F;     subClass.prototype._super = superClass.prototype;     subClass.prototype.constructor = subClass;   }; }(); console .log(child.constructor === Child);  console .log(child.constructor === Parent);  
同时,也如《关于JavaScript中的继承(二):原型式继承》 中提到的那样,利用闭包来减少每次调用inherit()都会生成一个临时构造函数的开销。  
写在最后,类式继承为我们带来了JavaScript中不存在的完整的类的概念,这对于从面向对象语言转过来的程序员来说,可能是很好的方式。但是它也有可能让我们忽略了JavaScript真正的原型式继承。不过这些模式都没有好与坏之分,应该在适合的场景使用合适的方法才是。