如何在JS构造函数中调用原型函数方法?非类实现问询
问题分析
你的代码里存在几个核心问题导致无法访问printName:
Car构造函数直接返回了一个独立对象,调用Car.call(this)时,这个返回的对象并没有和Toyota/Honda的实例上下文绑定,相当于白调用了。Toyota和Honda最后也返回了新对象,直接覆盖了new操作创建的实例,使得之前的Car.call(this)完全失效。print函数内部找不到printName的作用域,自然无法调用。
下面是几种纯函数式的修复方案:
方案1:将Car的方法挂载到实例this上
修改Car的写法,不返回新对象,而是把方法挂载到构造函数的this上(也就是实例本身):
function Car() { this.printName = function(name) { console.log(`this model is ${name}`); }; } function Toyota() { // 调用Car,把printName挂载到当前Toyota实例的this上 Car.call(this); // 不要返回新对象,保留new创建的实例 this.print = function() { this.printName('toyota'); }; } function Honda() { Car.call(this); this.print = function() { this.printName('honda'); }; } var toyota = new Toyota(); var honda = new Honda(); toyota.print(); // 输出: this model is toyota honda.print(); // 输出: this model is honda
方案2:保存Car返回的对象引用
如果必须保留Car返回对象的写法,可以在Toyota/Honda内部保存这个返回的对象,直接调用其方法:
function Car() { return { printName: function(name) { console.log(`this model is ${name}`); } }; } function Toyota() { // 保存Car返回的对象 const carInstance = Car.call(this); return { print: function() { carInstance.printName('toyota'); } }; } function Honda() { const carInstance = Car.call(this); return { print: function() { carInstance.printName('honda'); } }; } var toyota = new Toyota(); var honda = new Honda(); toyota.print(); // 输出: this model is toyota honda.print(); // 输出: this model is honda
方案3:原型链继承
利用JavaScript的原型机制,让Toyota/Honda的原型继承Car的原型,实现方法共享:
function Car() {} // 把printName挂载到Car的原型上 Car.prototype.printName = function(name) { console.log(`this model is ${name}`); }; function Toyota() { this.print = function() { // 通过原型链找到Car.prototype上的printName this.printName('toyota'); }; } // 让Toyota的原型指向Car原型的副本,实现继承 Toyota.prototype = Object.create(Car.prototype); // 修正构造函数指向,避免原型链混乱 Toyota.prototype.constructor = Toyota; function Honda() { this.print = function() { this.printName('honda'); }; } Honda.prototype = Object.create(Car.prototype); Honda.prototype.constructor = Honda; var toyota = new Toyota(); var honda = new Honda(); toyota.print(); // 输出: this model is toyota honda.print(); // 输出: this model is honda
内容的提问来源于stack exchange,提问作者Oleksiy Kyrylenko
相关产品推荐
相关产品推荐

