JavaScript Object Get/Set
Understanding getters and setters for controlled property access
🎛️ What are Getters and Setters?
Getters and setters are special methods that allow you to define how properties are accessed and modified. They provide a way to control and validate property access while keeping the syntax simple.
let person = {
get fullName() { return this.first + " " + this.last; },
set fullName(value) { [this.first, this.last] = value.split(" "); }
};
Getter and Setter Concepts
Getters
Control how properties are read
get propertyName() {
return this._value;
}
Setters
Control how properties are written
set propertyName(value) {
this._value = value;
}
Validation
Validate data before setting
set age(value) {
if (value < 0) throw new Error("Invalid age");
this._age = value;
}
Computed Properties
Calculate values dynamically
get area() {
return this.width * this.height;
}
🔹 Basic Getters and Setters
Simple example of getters and setters in action:
let person = {
firstName: "John",
lastName: "Doe",
// Getter - computed property
get fullName() {
return this.firstName + " " + this.lastName;
},
// Setter - splits full name into parts
set fullName(value) {
let parts = value.split(" ");
this.firstName = parts[0] || "";
this.lastName = parts[1] || "";
},
// Getter for formatted display
get displayName() {
return this.lastName + ", " + this.firstName;
}
};
// Using the getter (looks like a property)
console.log("Full name:", person.fullName); // "John Doe"
console.log("Display name:", person.displayName); // "Doe, John"
// Using the setter (looks like assigning to a property)
person.fullName = "Jane Smith";
console.log("First name:", person.firstName); // "Jane"
console.log("Last name:", person.lastName); // "Smith"
console.log("Full name:", person.fullName); // "Jane Smith"
Output:
Full name: John Doe
Display name: Doe, John
First name: Jane
Last name: Smith
Full name: Jane Smith
🔹 Getters and Setters with Validation
Use setters to validate data before storing:
let user = {
_email: "",
_age: 0,
// Email getter and setter with validation
get email() {
return this._email;
},
set email(value) {
// Simple email validation
if (value.includes("@") && value.includes(".")) {
this._email = value;
} else {
console.log("Invalid email format!");
}
},
// Age getter and setter with validation
get age() {
return this._age;
},
set age(value) {
if (typeof value === "number" && value >= 0 && value <= 150) {
this._age = value;
} else {
console.log("Age must be a number between 0 and 150!");
}
},
// Computed property based on age
get category() {
if (this._age < 13) return "child";
if (this._age < 20) return "teenager";
if (this._age < 60) return "adult";
return "senior";
}
};
// Test the validation
user.email = "[email protected]"; // Valid
user.age = 25; // Valid
console.log("Email:", user.email); // "[email protected]"
console.log("Age:", user.age); // 25
console.log("Category:", user.category); // "adult"
// Test invalid values
user.email = "invalid-email"; // Shows error message
user.age = -5; // Shows error message
user.age = 200; // Shows error message
console.log("Email after invalid:", user.email); // Still "[email protected]"
console.log("Age after invalid:", user.age); // Still 25
Output:
Email: [email protected]
Age: 25
Category: adult
Invalid email format!
Age must be a number between 0 and 150!
Age must be a number between 0 and 150!
Email after invalid: [email protected]
Age after invalid: 25
🔹 Using Object.defineProperty()
Define getters and setters using Object.defineProperty():
let rectangle = {
width: 0,
height: 0
};
// Define getter and setter using Object.defineProperty
Object.defineProperty(rectangle, 'area', {
get: function() {
console.log("Calculating area...");
return this.width * this.height;
},
enumerable: true, // Shows up in for...in loops
configurable: true // Can be deleted or reconfigured
});
Object.defineProperty(rectangle, 'perimeter', {
get: function() {
return 2 * (this.width + this.height);
},
enumerable: true
});
// Define a setter for dimensions
Object.defineProperty(rectangle, 'dimensions', {
set: function(value) {
if (Array.isArray(value) && value.length === 2) {
this.width = value[0];
this.height = value[1];
} else {
console.log("Dimensions must be an array of [width, height]");
}
},
enumerable: false // Won't show up in for...in loops
});
// Test the properties
rectangle.width = 5;
rectangle.height = 3;
console.log("Area:", rectangle.area); // 15 (with log message)
console.log("Perimeter:", rectangle.perimeter); // 16
// Use the setter
rectangle.dimensions = [10, 8];
console.log("New area:", rectangle.area); // 80
console.log("New perimeter:", rectangle.perimeter); // 36
// Check enumerable properties
console.log("Enumerable properties:", Object.keys(rectangle));
Output:
Calculating area...
Area: 15
Perimeter: 16
Calculating area...
New area: 80
New perimeter: 36
Enumerable properties: ["width", "height", "area", "perimeter"]
🔹 Class-based Getters and Setters
Using getters and setters in ES6 classes:
class Temperature {
constructor(celsius = 0) {
this._celsius = celsius;
}
// Getter for Celsius
get celsius() {
return this._celsius;
}
// Setter for Celsius with validation
set celsius(value) {
if (typeof value === "number" && value >= -273.15) {
this._celsius = value;
} else {
throw new Error("Temperature cannot be below absolute zero (-273.15°C)");
}
}
// Getter for Fahrenheit (computed property)
get fahrenheit() {
return (this._celsius * 9/5) + 32;
}
// Setter for Fahrenheit
set fahrenheit(value) {
this.celsius = (value - 32) * 5/9;
}
// Getter for Kelvin
get kelvin() {
return this._celsius + 273.15;
}
// Setter for Kelvin
set kelvin(value) {
this.celsius = value - 273.15;
}
// Method to get description
get description() {
if (this._celsius < 0) return "Freezing";
if (this._celsius < 10) return "Cold";
if (this._celsius < 25) return "Cool";
if (this._celsius < 35) return "Warm";
return "Hot";
}
}
// Create temperature object
let temp = new Temperature(25);
console.log("Celsius:", temp.celsius); // 25
console.log("Fahrenheit:", temp.fahrenheit); // 77
console.log("Kelvin:", temp.kelvin); // 298.15
console.log("Description:", temp.description); // "Warm"
// Change temperature using different scales
temp.fahrenheit = 100;
console.log("After setting to 100°F:");
console.log("Celsius:", temp.celsius); // ~37.78
console.log("Description:", temp.description); // "Hot"
temp.kelvin = 273.15;
console.log("After setting to 273.15K:");
console.log("Celsius:", temp.celsius); // 0
console.log("Fahrenheit:", temp.fahrenheit); // 32
Output:
Celsius: 25
Fahrenheit: 77
Kelvin: 298.15
Description: Warm
After setting to 100°F:
Celsius: 37.77777777777778
Description: Hot
After setting to 273.15K:
Celsius: 0
Fahrenheit: 32
🔹 Practical Examples
Real-world use cases for getters and setters:
// Example 1: Shopping Cart with automatic calculations
let shoppingCart = {
_items: [],
get items() {
return this._items;
},
set items(newItems) {
this._items = Array.isArray(newItems) ? newItems : [];
},
get totalPrice() {
return this._items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
},
get itemCount() {
return this._items.reduce((sum, item) => sum + item.quantity, 0);
},
addItem(name, price, quantity = 1) {
this._items.push({name, price, quantity});
}
};
// Example 2: User profile with automatic formatting
let userProfile = {
_firstName: "",
_lastName: "",
_birthYear: null,
get firstName() { return this._firstName; },
set firstName(value) {
this._firstName = typeof value === "string" ? value.trim() : "";
},
get lastName() { return this._lastName; },
set lastName(value) {
this._lastName = typeof value === "string" ? value.trim() : "";
},
get fullName() {
return `${this._firstName} ${this._lastName}`.trim();
},
get age() {
return this._birthYear ? new Date().getFullYear() - this._birthYear : null;
},
set birthYear(year) {
let currentYear = new Date().getFullYear();
if (year > 1900 && year <= currentYear) {
this._birthYear = year;
}
}
};
// Test shopping cart
shoppingCart.addItem("Laptop", 999, 1);
shoppingCart.addItem("Mouse", 25, 2);
console.log("Cart total:", shoppingCart.totalPrice); // 1049
console.log("Item count:", shoppingCart.itemCount); // 3
// Test user profile
userProfile.firstName = " john ";
userProfile.lastName = " doe ";
userProfile.birthYear = 1990;
console.log("Full name:", userProfile.fullName); // "john doe"
console.log("Age:", userProfile.age); // Current year - 1990
Output:
Cart total: 1049
Item count: 3
Full name: john doe
Age: 34