JavaScript对象
对象是JavaScript的核心概念,是一种复合数据类型,用于存储键值对集合和复杂数据结构。在JavaScript中,几乎所有的东西都是对象。
对象的概念
对象是由属性和方法组成的集合:
- 属性:对象的特征,描述对象的状态
- 方法:对象的行为,描述对象可以执行的操作
创建对象的方法
1. 对象字面量
使用花括号 {} 创建对象,是最常用的创建对象的方法。
// 对象字面量创建对象
const person = {
name: 'Alice',
age: 30,
occupation: 'Engineer',
greet: function() {
console.log(`Hello, my name is ${this.name}!`);
}
};
console.log(person.name); // Alice
person.greet(); // Hello, my name is Alice!2. 构造函数
使用 new Object() 构造函数创建对象。
// 构造函数创建对象
const car = new Object();
car.brand = 'Toyota';
car.model = 'Camry';
car.year = 2023;
car.start = function() {
console.log('Car started!');
};
console.log(car.brand); // Toyota
car.start(); // Car started!3. 自定义构造函数
创建自定义构造函数来实例化多个相似的对象。
// 自定义构造函数
function Book(title, author, year) {
this.title = title;
this.author = author;
this.year = year;
this.getInfo = function() {
return `${this.title} by ${this.author}, published in ${this.year}`;
};
}
// 使用自定义构造函数创建对象实例
const book1 = new Book('JavaScript: The Good Parts', 'Douglas Crockford', 2008);
const book2 = new Book('Eloquent JavaScript', 'Marijn Haverbeke', 2018);
console.log(book1.getInfo()); // JavaScript: The Good Parts by Douglas Crockford, published in 2008
console.log(book2.getInfo()); // Eloquent JavaScript by Marijn Haverbeke, published in 20184. Object.create()方法
使用 Object.create() 方法创建对象,允许指定对象的原型。
// 使用Object.create()创建对象
const animal = {
type: 'Unknown',
makeSound: function() {
console.log('Some generic sound');
}
};
const dog = Object.create(animal);
dog.type = 'Dog';
dog.makeSound = function() {
console.log('Woof!');
};
console.log(dog.type); // Dog
dog.makeSound(); // Woof!访问对象属性
1. 点表示法
使用 . 访问对象属性,是最常用的方法。
const person = { name: 'Bob', age: 25 };
console.log(person.name); // Bob
console.log(person.age); // 252. 方括号表示法
使用 [] 访问对象属性,适用于属性名包含特殊字符或动态属性名。
const person = { 'full name': 'Charlie Brown', age: 10 };
console.log(person['full name']); // Charlie Brown
// 动态属性名
const propertyName = 'age';
console.log(person[propertyName]); // 10修改对象
添加属性
const person = { name: 'David' };
person.age = 35;
person['occupation'] = 'Teacher';
console.log(person); // { name: 'David', age: 35, occupation: 'Teacher' }修改属性
const person = { name: 'Eve', age: 28 };
person.age = 29;
person.name = 'Eva';
console.log(person); // { name: 'Eva', age: 29 }删除属性
使用 delete 关键字删除对象的属性。
const person = { name: 'Frank', age: 40, occupation: 'Doctor' };
delete person.occupation;
console.log(person); // { name: 'Frank', age: 40 }对象的属性类型
数据属性
用于存储数据值,具有以下特性:
value:属性的值writable:是否可修改属性值enumerable:是否可枚举(for...in循环中可见)configurable:是否可配置(是否可删除或修改特性)
访问器属性
用于访问和修改属性,具有以下特性:
get:获取属性值的函数set:设置属性值的函数enumerable:是否可枚举configurable:是否可配置
// 访问器属性示例
const person = {
_firstName: 'Grace',
_lastName: 'Hopper',
get fullName() {
return `${this._firstName} ${this._lastName}`;
},
set fullName(name) {
const parts = name.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
}
};
console.log(person.fullName); // Grace Hopper
person.fullName = 'Ada Lovelace';
console.log(person.fullName); // Ada Lovelace
console.log(person._firstName); // Ada对象的遍历
1. for...in循环
遍历对象的可枚举属性(包括继承的属性)。
const person = { name: 'Henry', age: 32, occupation: 'Developer' };
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
// name: Henry
// age: 32
// occupation: Developer2. Object.keys()
返回对象自身的可枚举属性的数组。
const person = { name: 'Ivy', age: 27, occupation: 'Designer' };
const keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'occupation']
keys.forEach(key => {
console.log(`${key}: ${person[key]}`);
});3. Object.values()
返回对象自身的可枚举属性值的数组。
const person = { name: 'Jack', age: 45, occupation: 'Manager' };
const values = Object.values(person);
console.log(values); // ['Jack', 45, 'Manager']4. Object.entries()
返回对象自身的可枚举属性键值对的数组。
const person = { name: 'Kate', age: 29, occupation: 'Nurse' };
const entries = Object.entries(person);
console.log(entries); // [['name', 'Kate'], ['age', 29], ['occupation', 'Nurse']]
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});对象的方法
Object.assign()
用于合并对象,将源对象的属性复制到目标对象。
// 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 }Object.freeze()
冻结对象,使其不能被修改(不能添加、修改或删除属性)。
// Object.freeze()示例
const frozenObject = { a: 1, b: 2 };
Object.freeze(frozenObject);
frozenObject.c = 3; // 不会生效
frozenObject.a = 10; // 不会生效
delete frozenObject.b; // 不会生效
console.log(frozenObject); // { a: 1, b: 2 }Object.seal()
密封对象,使其不能添加或删除属性,但可以修改现有属性。
// Object.seal()示例
const sealedObject = { a: 1, b: 2 };
Object.seal(sealedObject);
sealedObject.c = 3; // 不会生效
sealedObject.a = 10; // 可以生效
delete sealedObject.b; // 不会生效
console.log(sealedObject); // { a: 10, b: 2 }对象的继承
JavaScript使用原型链实现继承,每个对象都有一个原型对象,对象可以继承原型对象的属性和方法。
// 原型继承示例
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound.`);
};
function Dog(name, breed) {
Animal.call(this, name); // 调用父构造函数
this.breed = breed;
}
// 设置Dog的原型为Animal的实例
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 重写speak方法
Dog.prototype.speak = function() {
console.log(`${this.name} barks.`);
};
const dog = new Dog('Buddy', 'Golden Retriever');
dog.speak(); // Buddy barks.
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true对象的最佳实践
- 使用对象字面量创建对象,简洁易读
- 使用驼峰命名法命名属性和方法
- 避免使用全局对象,防止命名冲突
- 使用Object.keys()、Object.values()和Object.entries()遍历对象
- 合理使用原型继承,避免不必要的属性复制
- 使用访问器属性封装复杂逻辑
- 考虑使用ES6的class语法创建对象(后续章节介绍)