10. Objects and Prototypes
Object Creation
Object Literal
const person = {
name: "John",
age: 30,
greet: function() {
return `Hello, I'm ${this.name}`;
}
};
console.log(person.name); // "John"
console.log(person.greet()); // "Hello, I'm John"
Constructor Function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
return `Hello, I'm ${this.name}`;
};
}
const john = new Person("John", 30);
console.log(john.greet()); // "Hello, I'm John"
Object.create()
const personPrototype = {
greet: function() {
return `Hello, I'm ${this.name}`;
}
};
const john = Object.create(personPrototype);
john.name = "John";
john.age = 30;
console.log(john.greet()); // "Hello, I'm John"
Properties and Methods
Adding Properties
const car = {};
// Dot notation
car.make = "Toyota";
car.model = "Camry";
// Bracket notation
car["year"] = 2020;
car["color"] = "blue";
console.log(car); // { make: "Toyota", model: "Camry", year: 2020, color: "blue" }
Accessing Properties
const person = {
name: "John",
age: 30,
"first-name": "John" // Property with special characters
};
// Dot notation
console.log(person.name); // "John"
// Bracket notation
console.log(person["age"]); // 30
console.log(person["first-name"]); // "John"
// Dynamic property access
const property = "name";
console.log(person[property]); // "John"
Property Descriptors
const person = {};
Object.defineProperty(person, "name", {
value: "John",
writable: true, // Can change value
enumerable: true, // Shows in for...in loops
configurable: true // Can delete or reconfigure
});
Object.defineProperty(person, "age", {
get: function() {
return this._age || 0;
},
set: function(value) {
this._age = value > 0 ? value : 0;
},
enumerable: true,
configurable: true
});
person.age = 30;
console.log(person.age); // 30
person.age = -5;
console.log(person.age); // 0
Prototypes
Understanding Prototypes
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
const john = new Person("John");
console.log(john.greet()); // "Hello, I'm John"
// Check prototype
console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
Prototype Chain
const grandparent = { a: 1 };
const parent = Object.create(grandparent);
parent.b = 2;
const child = Object.create(parent);
child.c = 3;
console.log(child.a); // 1 (inherited from grandparent)
console.log(child.b); // 2 (inherited from parent)
console.log(child.c); // 3 (own property)
instanceof Operator
function Animal(name) {
this.name = name;
}
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const dog = new Dog("Buddy", "Golden Retriever");
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog instanceof Object); // true
Object Methods
Object.keys(), Object.values(), Object.entries()
const person = {
name: "John",
age: 30,
city: "New York"
};
console.log(Object.keys(person)); // ["name", "age", "city"]
console.log(Object.values(person)); // ["John", 30, "New York"]
console.log(Object.entries(person)); // [["name", "John"], ["age", 30], ["city", "New York"]]
Object.assign()
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
console.log(target); // { a: 1, b: 2, c: 3 }
// Shallow copy
const original = { a: 1, b: { c: 2 } };
const copy = Object.assign({}, original);
copy.b.c = 3;
console.log(original.b.c); // 3 (modified!)
Object.freeze(), Object.seal()
const obj = { a: 1, b: 2 };
// Freeze: prevents adding, deleting, modifying properties
Object.freeze(obj);
obj.a = 3; // No effect in strict mode
obj.c = 4; // No effect
delete obj.b; // No effect
// Seal: prevents adding, deleting properties but allows modification
const obj2 = { x: 1, y: 2 };
Object.seal(obj2);
obj2.x = 3; // OK
obj2.z = 4; // No effect
delete obj2.y; // No effect
JSON
JSON.stringify()
const person = {
name: "John",
age: 30,
hobbies: ["reading", "coding"]
};
const jsonString = JSON.stringify(person);
console.log(jsonString); // '{"name":"John","age":30,"hobbies":["reading","coding"]}'
JSON.parse()
const jsonString = '{"name":"John","age":30}';
const person = JSON.parse(jsonString);
console.log(person.name); // "John"
Next Steps
Objects and prototypes form the foundation of JavaScript's object-oriented programming. Next, let's explore classes, the modern way to create objects in ECMAScript.