JavaScript中使用变量调用Getter/Setter的技术问询及代码疑问
Great question—let’s unpack both parts of your inquiry clearly and practically.
1. How to Use Variables to Call Getters/Setters in JavaScript
In JavaScript, getters and setters are special object/class properties that execute functions when you access or assign to them. To call a getter or setter using a variable, you can use bracket notation—the same way you’d access a dynamic property on any object.
Here’s a concrete example to show how it works:
class MealGenerator { constructor() { this._appetizers = [{name: 'Bruschetta'}, {name: 'Caesar Salad'}]; this._mainCourses = [{name: 'Grilled Steak'}, {name: 'Baked Salmon'}]; } // Getter for appetizers get appetizers() { // Imagine adding future logic here, like filtering out unavailable dishes return this._appetizers; } // Getter for main courses get mainCourses() { return this._mainCourses; } getRandomDish(courseType) { // Use bracket notation to trigger the getter with a variable const dishes = this[courseType]; const randomIndex = Math.floor(Math.random() * dishes.length); return dishes[randomIndex]; } } const generator = new MealGenerator(); console.log(generator.getRandomDish('appetizers')); // Random appetizer object
When you write this[courseType], JavaScript recognizes the string stored in courseType matches a getter name, and automatically runs the getter function—just like if you’d written this.appetizers directly. For setters, the same logic applies: you’d use this[variableName] = newValue to trigger the setter.
2. Evaluating the Codecademy Solution’s Approach
Looking at the code snippet you shared, I assume there’s a small typo in getRandomDishFromCourse (it should return this._courses[courseName] instead of hardcoding 'appetizers' to make the parameter useful). With that fixed, let’s break down the approach:
Pros of the Codecademy Implementation
- It’s simple for basic use cases: Directly accessing the
_coursesobject’s properties is easy to read, especially if_coursesis just a plain object storing dish arrays with no extra logic. - It avoids minor overhead: If your getters only return the private property without any additional processing, directly accessing
_courses[courseName]skips the getter function call entirely.
Cons & Better Practices to Consider
- It breaks encapsulation: The leading underscore on
_coursessignals it’s a private internal property. By accessing it directly, you bypass any getters you might add later. For example, if you update a getter to filter out out-of-stock dishes or sort results,getRandomDishFromCoursewon’t inherit that logic unless you rewrite it. - It’s less flexible: If you ever refactor the class to use separate private properties (like
_appetizersinstead of_courses.appetizers), you’ll have to rewritegetRandomDishFromCoursecompletely.
A more maintainable approach would be to use the getter with bracket notation, like this:
getRandomDishFromCourse(courseName) { const dishes = this[courseName]; // Triggers the getter for the specified course const randomIndex = Math.floor(Math.random() * dishes.length); return dishes[randomIndex]; }
This way, you rely on the class’s public interface (the getters) instead of poking at internal details. It keeps your code decoupled from the class’s internal structure, making future changes easier.
内容的提问来源于stack exchange,提问作者Lukas Arvidsson

