Node JS TypeError排查:无法读取undefined的'CONTEXT_1'属性
Let's walk through exactly why you're hitting this error and how to fix it—no jargon, just straight to the point.
What's Causing the Error?
You've got two key issues here:
- Circular Dependency:
orderManager.jsimportsnotificationManager.js, andnotificationManager.jsimportsorderManager.js. Node.js can't fully resolve both modules at the same time, so one ends up with an incomplete export (hence theundefinedwhen trying to accessorderContext). - Wrong Export Type: In
orderManager.js, you're exporting an instance oforderManager(fromorderManager.bootstrap()), not the constructor/class itself. But innotificationManager.js, you're trying to accessorderManager.orderContext—which is defined on the constructor's prototype, not the instance. Even without the loop, this would fail.
Step-by-Step Fix
Let's adjust the code to fix both issues, starting with the module exports.
1. Update orderManager.js
We'll export both the constructor and the instance, and expose orderContext as a static property so other modules can access it easily:
const notificationManager = require("./notificationManager"); var orderManager = (function() { function orderManager() { console.log("orderManager"); }; orderManager.bootstrap = function() { console.log("orderManager.bootstrap"); return new orderManager(); }; // Define context on prototype as before orderManager.prototype.orderContext = { "CONTEXT_1": "context_1", "CONTEXT_2": "context_2", "CONTEXT_3": "context_3" }; // Expose context as a static property for external access orderManager.orderContext = orderManager.prototype.orderContext; orderManager.prototype.notify = function() { var dataObj = {}; notificationManager.sendToClient(dataObj); }; return orderManager; }()); // Export constructor + instance instead of just the instance module.exports = { OrderManager: orderManager, instance: orderManager.bootstrap() };
2. Fix notificationManager.js
We'll break the circular dependency with a lazy require (inside the method instead of the top), and access the correct static orderContext:
var notificationManager = (function() { function notificationManager() { console.log("notificationManager"); }; notificationManager.bootstrap = function() { console.log("notificationManager.bootstrap"); return new notificationManager(); }; notificationManager.prototype.sendToClient = function(dataObj) { console.log("notificationManager.prototype.sendToClient"); // Lazy require here to avoid circular dependency const { OrderManager } = require("./orderManager"); var _this = this; // Guard clause: make sure we have the orderContext before using it if (!_this.request?.body?.orderContext) { console.warn("Missing orderContext in request body—can't proceed with notification"); return; } switch (_this.request.body.orderContext) { case OrderManager.orderContext.CONTEXT_1: notifyClient(_this, dataObj); break; // Add other context cases here if needed } }; // Make sure notifyClient is defined (add this if it's missing) function notifyClient(manager, data) { console.log("Sending notification to client:", data); // Your actual client notification logic goes here } return notificationManager; }()); module.exports = notificationManager.bootstrap();
Why This Works
- No More Circular Dependency: By requiring
orderManagerinside thesendToClientmethod instead of at the top, we let Node.js fully resolve both modules before the require runs. - Correct Context Access: We now access
OrderManager.orderContext(the static property we added) instead of trying to get it from an instance. - Guard Clause: We added a check to avoid errors if
request.body.orderContextis missing—this prevents unexpected crashes down the line.
Bonus: Even Better Structure (Optional)
For long-term maintainability, move shared constants like orderContext to a separate file. This eliminates circular dependencies entirely:
// orderContext.js module.exports = { CONTEXT_1: "context_1", CONTEXT_2: "context_2", CONTEXT_3: "context_3" };
Then import this file into both orderManager.js and notificationManager.js instead of relying on each other.
内容的提问来源于stack exchange,提问作者Hiren Makwana

