Odoo 15中JS如何调用父类方法?关于_super的疑问
Odoo中JavaScript的
_super用法解析 问题描述
我需要明确JavaScript中_super的相关用法。尝试继承一个Widget并调用父类方法时,试过多种调用方式但只有一种有效。分析Odoo源码时发现,不同场景下Odoo会用不同的父类方法调用方式,想知道原因。
示例代码
odoo.define('pos_session_route.payment', function (require) { "use strict"; var account_payment = require('account.payment'); var AbstractField = require('web.AbstractField'); var core = require('web.core'); var field_registry = require('web.field_registry'); var QWeb = core.qweb; var _t = core._t; console.log('paymenyyyyy',account_payment); account_payment.ShowPaymentLineWidget.include({ // AbstractField.include({ payment_widget : function () { console.log('paymenyyyyy'); }, _render:function(){ console.log('hihooo'); // account_payment.prototype._super.apply(this.arguments); didn't work // account_payment.ShowPaymentLineWidget.prototype._super.apply(this.arguments); didn't work // this._super.apply(this, arguments);didn't work this._super(this.arguments); // it works } }) });
用法解析
为什么只有this._super(this.arguments)有效?
Odoo的include机制是对类原型做动态扩展,被include的方法内部会由框架自动注入_super方法,指向父类的原方法:
this._super是Odoo封装的语法糖,不是原生JS特性,它已经帮你处理了上下文绑定和参数传递逻辑。- 前两种直接访问类
prototype._super的写法无效,因为_super是方法调用时动态挂载到实例上下文的,不是类原型上的公共属性。 - 第三种
this._super.apply(this, arguments)理论上语法没问题,可能是当时代码上下文或参数传递的细节问题导致失效;而this._super(this.arguments)能生效,是因为Odoo的_super内部兼容了这种参数传递方式,更推荐的写法是this._super(...arguments)(用扩展运算符解构参数)。
Odoo不同场景下调用方式差异的原因
Odoo里父类方法的调用方式对应不同的继承场景:
this._super(...):这是最常用的写法,适用于include扩展方法或extend创建子类的场景。框架会自动为当前方法绑定_super,直接指向父类对应方法,无需手动处理原型和上下文。ParentClass.prototype.method.call(this, ...):当你没有用Odoo的include/extend机制,而是用原生JS修改原型,或者需要在子类新方法里调用父类的某个特定方法(不是当前重写的方法)时,会用这种方式,本质是原生JS的原型调用逻辑。_super.call(this, ...):多见于Odoo早期版本或底层类继承,因为当时框架封装逻辑不同,_super是作为方法内部变量存在,而非挂载在this上。
核心逻辑都是保证在子类或扩展方法中正确调用父类原方法,不同写法只是对应不同的框架封装实现和继承场景。
内容的提问来源于stack exchange,提问作者KbiR
相关产品推荐
相关产品推荐

