JS 的继承方案是逐步演进的:原型链继承把子类原型指向父类实例,缺点是引用类型被所有子类共享且无法传参;借用构造函数用 call 改变 this,解决了传参但拿不到父类原型上的方法;组合式继承把两者结合是 ES5 时代的标准答案;寄生组合式继承用 Object.create 优化掉父类构造函数的多余执行,是最完善的 ES5 方案。
ES6 的 class 用 extends 与 super 写起来更像面向对象语言,本质上仍是基于原型的语法糖。面试要求是能把 ES5 的寄生组合式写出来,并说清 super 在构造函数中的调用相当于父类构造函数借用。延伸考点是 new.target 与抽象类的模拟。
// 寄生组合式继承(ES5 最优方案) function inherit(Sub, Sup) { Sub.prototype = Object.create(Sup.prototype); Sub.prototype.constructor = Sub; } function Animal(name) { this.name = name; } Animal.prototype.eat = function () { return this.name + ' is eating'; }; function Dog(name, breed) { Animal.call(this, name); // 借用构造函数:继承实例属性 this.breed = breed; } inherit(Dog, Animal); Dog.prototype.bark = function () { return this.name + ' says woof'; }; const d = new Dog('Buddy', 'Golden'); console.log(d.eat(), d.bark(), d instanceof Animal); // ES6 写法:class extends 是同样机制的语法糖