咱们先说说那个老问题,为啥子类搞出来的对象,感觉跟父类没啥关系?这其实是以前的那种组合继承留下的尴尬事儿。虽然那种写法把构造函数和原型链混用,看着挺全面,可要是用 instanceof 去查,你会发现它只能证明子类的原型链上有父类的影子,根本没法直接在子类里访问到父类的方法。 为了解决这个硬伤,寄生组合式继承就派上用场了。它的核心思路挺简单,就是借 ES5 的 Object.create 这个神器来帮忙,直接把父类的原型完整地“克隆”一份。不用再像以前那样写一堆繁琐的 inheritObject() 函数了,直接把克隆出来的副本挂到子类的原型上就行。 这么一来,你创建的 SubClass 对象,既是 SubClass 构造函数的实例,也是 SuperClass 的实例。问题一下子就全解决了。 具体的实现步骤也不复杂。咱们先定义一个父类 SuperClass,它有个 getName 方法,还能带个名字。然后再搞个子类 SubClass,调用 SuperClass.call 来借用构造函数的属性。 重点来了!要给子类挂上父类的原型。咱们写个小函数叫 inheritPrototype,先通过 Object.create 搞一份父类原型的副本,再把这个副本设为子类的原型。最后记得把构造器指针指回子类自己。 接着,你还能给子类的原型加上自己的方法,比如 getTime。 这就搞定了!这时候的 SubClass 既有父类的属性和方法,又不会重复去实例化父类。 这种写法最大的好处有俩:一是只实例化一次父类,省了不少性能开销;二是完全兼容 instanceof,子类既能是父类的实例,也能顺着原型链找到父类的方法。 不过这儿有个坑得注意,千万别拿子类原型当普通对象直接赋值。如果你用点语法给 SubClass.prototype 乱写东西,很容易就把刚才借来的那个副本给覆盖了。要是想再扩展点方法,必须老老实实写 SubClass.prototype.新方法 = function() {...},不然就得遭殃。 说白了,这就是“借用构造函数 + 浅拷贝父类原型”的组合打法。它一次性解决了“子类不是父类实例”和“重复实例化父类”这两个大难题,是 JavaScript 面向对象编程里最干净、最高效的继承方案。掌握了这个,你就拿到了写高效、好维护类的终极钥匙。