Odoo中Javascript类的extend与include方法有何区别?
Hey folks! Let’s clear up the difference between extend and include in Odoo’s JavaScript framework—they’re both used to modify class behavior, but they work in totally different ways that matter a lot for your code’s structure and impact.
At a high level:
extend()creates a brand-new subclass that inherits from the original class (leaving the original untouched)include()modifies the original class in-place, changing how all its existing and future instances behave
1. extend(): Build a Custom Subclass
When you use extend, you’re creating a separate, standalone class that inherits all properties and methods from the parent. The original class stays exactly as it was—no changes, no side effects for other code using it.
Example
Suppose we want a custom version of Odoo’s base Widget class without altering the default Widget behavior:
const MyCustomDashboardWidget = Widget.extend({ // Override the parent's start method start: function() { // Call the original Widget's start method first this._super(...arguments); // Add our custom logic this.$el.addClass('custom-dashboard-style'); console.log("Custom dashboard widget initialized!"); }, // Add a new method unique to our subclass refreshData: function() { console.log("Refreshing dashboard data..."); } });
Key Traits of extend()
- No impact on parent class: The original
Widgetclass and all its existing instances remain unchanged - Isolated customization: Only instances of
MyCustomDashboardWidgetwill have the new method and modifiedstartlogic - Safe for targeted changes: Perfect when you need a specialized variant of a class without risking breakage elsewhere in the system
2. include(): Modify the Original Class Globally
include() directly alters the prototype of the original class. This means every instance of that class (and any subclasses that inherit from it)—whether they were created before or after your include call—will use the modified behavior.
Example
If we want to add a debug log to every Widget instance in the system:
Widget.include({ start: function() { // Call the original start method to preserve default behavior this._super(...arguments); // Add our global logic console.log(`Widget ${this.name} initialized (global debug log)`); } });
Key Traits of include()
- Global impact: Every
Widget(and any class that extendsWidget) will now run this modifiedstartmethod - In-place modification: You’re not creating a new class—you’re changing the original one
- Powerful but risky: Great for adding cross-cutting features (like logging, analytics, or global UI tweaks), but can cause unexpected side effects if you override methods without preserving the original logic with
_super()
3. Side-by-Side Comparison
| Aspect | extend() | include() |
|---|---|---|
| Effect on Original Class | Leaves parent class completely untouched | Modifies parent class prototype directly |
| Instance Scope | Only affects instances of the new subclass | Affects all existing/future instances of the original class (and its subclasses) |
| Primary Use Case | Building specialized variants of a class | Adding global functionality to all instances of a class |
| Safety | Low risk (isolated changes) | Higher risk (can break existing code) |
Pro Tip
In both cases, use this._super(...arguments) to call the original class’s method before adding your custom logic. This preserves the default behavior while letting you extend it—critical for avoiding bugs in Odoo’s core functionality.
内容的提问来源于stack exchange,提问作者Developer Marius Žilėnas

