JavaScript中对象属性返回undefined问题求助(附Tree类代码)
Let's dig into why you're seeing those pesky undefined errors with your Tree class, and get it sorted out step by step.
The Root Cause: Incorrect Array Traversal
The biggest culprit here is your use of for...in to loop through the children array in the pour method.
for...in is designed to iterate over all enumerable properties of an object, not just array elements. If your array ever gains extra properties (even accidentally, like if someone adds a method to Array.prototype), this loop will pick those up too. When that happens, this.children[child] will be undefined, and calling undefined.pour() throws the error you're seeing.
Quick Fix: Use Array-Friendly Iteration
Replace that for...in loop with a method built for arrays. Here are a few solid options:
Option 1: forEach (cleanest for readability)
this.children.forEach(child => { child.pour(amount * .5); });
Option 2: for...of (great if you need break/continue logic)
for (const child of this.children) { child.pour(amount * .5); }
Option 3: Traditional for loop (most compatible with older environments)
for (let i = 0; i < this.children.length; i++) { this.children[i].pour(amount * .5); }
Bonus: Optimize Your Class Structure
While not directly causing the undefined issue, defining methods like pour and divide inside the constructor is inefficient—every new Tree instance will create duplicate copies of these functions. Instead, attach them to the prototype to share them across all instances:
// Constructor only handles instance properties function Tree() { this.capacity = 1; this.contents = 0; this.children = []; this.divided = false; } // Methods live on the prototype Tree.prototype.pour = function(amount) { this.contents += amount; if (this.contents <= 1) { return; } if (!this.divided) { this.divide(); } const overflow = this.contents - 1; this.contents = 1; this.children.forEach(child => { child.pour(overflow * 0.5); }); }; Tree.prototype.divide = function() { // Use map directly on the empty array (no need to fill first, though fill works too) this.children = Array.from({ length: 2 }, () => new Tree()); this.divided = true; };
Test It Out
If you run something like this now, you won't get undefined errors anymore:
const tree = new Tree(); tree.pour(3); // This will split into children correctly
内容的提问来源于stack exchange,提问作者Kyle Rosenberg

