Skip to content

JavaScript 对象

JavaScript 对象是该语言的核心概念之一,它是一种复合数据类型,用于存储键值对集合和更复杂的实体。对象是 JavaScript 中最强大的特性之一,几乎所有的 JavaScript 值(除了原始值)都是对象。在本章节中,我们将深入学习 JavaScript 对象的各个方面。

什么是对象

对象是属性的集合,每个属性都有一个键(也称为属性名)和一个值。值可以是原始值(如字符串、数字、布尔值)或其他对象,甚至是函数(称为方法)。

javascript
// 创建一个简单的对象
const person = {
    name: "张三",
    age: 25,
    isStudent: true
};

创建对象的方式

1. 对象字面量(推荐)

javascript
const person = {
    name: "张三",
    age: 25,
    greet: function() {
        return "你好,我是" + this.name;
    }
};

2. 使用 new Object()

javascript
const person = new Object();
person.name = "李四";
person.age = 30;
person.greet = function() {
    return "你好,我是" + this.name;
};

3. 使用构造函数

javascript
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        return "你好,我是" + this.name;
    };
}

const person1 = new Person("王五", 28);

4. 使用 Object.create()

javascript
const personPrototype = {
    greet: function() {
        return "你好,我是" + this.name;
    }
};

const person = Object.create(personPrototype);
person.name = "赵六";
person.age = 35;

属性的访问和设置

点表示法

javascript
const person = {
    name: "张三",
    age: 25
};

// 访问属性
console.log(person.name); // "张三"
console.log(person.age);  // 25

// 设置属性
person.age = 26;
person.city = "北京"; // 添加新属性

方括号表示法

javascript
const person = {
    name: "李四",
    age: 30
};

// 访问属性
console.log(person["name"]); // "李四"
console.log(person["age"]);  // 30

// 设置属性
person["age"] = 31;
person["city"] = "上海"; // 添加新属性

// 动态属性名
const propertyName = "hobby";
person[propertyName] = "读书";

特殊属性名

javascript
const obj = {
    "first name": "张",
    "last-name": "三",
    123: "数字键",
    true: "布尔键"
};

console.log(obj["first name"]); // "张"
console.log(obj["last-name"]);  // "三"
console.log(obj[123]);          // "数字键"
console.log(obj[true]);         // "布尔键"

属性的删除

javascript
const person = {
    name: "张三",
    age: 25,
    city: "北京"
};

// 删除属性
delete person.city;
console.log(person.city); // undefined

// 删除不存在的属性不会报错
delete person.nonExistent; // 返回 true

对象方法

对象中的函数称为方法:

javascript
const calculator = {
    add: function(a, b) {
        return a + b;
    },
    
    subtract: function(a, b) {
        return a - b;
    },
    
    // ES6 简写方法
    multiply(a, b) {
        return a * b;
    },
    
    divide(a, b) {
        if (b !== 0) {
            return a / b;
        } else {
            return "除数不能为零";
        }
    }
};

console.log(calculator.add(5, 3));      // 8
console.log(calculator.multiply(4, 2));  // 8

this 关键字

在对象方法中,[this](file:///C:/Workspace/Coding/WebProjects/tutorials-web/node_modules/typescript/lib/lib.es5.d.ts#L78-L82) 关键字引用调用该方法的对象:

javascript
const person = {
    name: "张三",
    age: 25,
    
    introduce: function() {
        return "我是" + this.name + ",今年" + this.age + "岁";
    },
    
    growOlder: function() {
        this.age++;
        return this.age;
    }
};

console.log(person.introduce()); // "我是张三,今年25岁"
console.log(person.growOlder()); // 26

对象的遍历

for...in 循环

javascript
const person = {
    name: "张三",
    age: 25,
    city: "北京"
};

for (let key in person) {
    console.log(key + ": " + person[key]);
}
// 输出:
// name: 张三
// age: 25
// city: 北京

Object.keys()

javascript
const person = {
    name: "李四",
    age: 30,
    city: "上海"
};

const keys = Object.keys(person);
console.log(keys); // ["name", "age", "city"]

keys.forEach(key => {
    console.log(key + ": " + person[key]);
});

Object.values()

javascript
const person = {
    name: "王五",
    age: 28,
    city: "广州"
};

const values = Object.values(person);
console.log(values); // ["王五", 28, "广州"]

Object.entries()

javascript
const person = {
    name: "赵六",
    age: 35,
    city: "深圳"
};

const entries = Object.entries(person);
console.log(entries); 
// [["name", "赵六"], ["age", 35], ["city", "深圳"]]

entries.forEach(([key, value]) => {
    console.log(key + ": " + value);
});

对象的属性描述符

JavaScript 允许更精细地控制对象属性:

javascript
const obj = {};

// 定义属性
Object.defineProperty(obj, "name", {
    value: "张三",
    writable: false,    // 不可写
    enumerable: true,   // 可枚举
    configurable: false // 不可配置
});

console.log(obj.name); // "张三"
obj.name = "李四";     // 无效,但在严格模式下会报错
console.log(obj.name); // 仍然是 "张三"

对象的冻结和密封

Object.freeze()

javascript
const obj = {
    name: "张三",
    age: 25
};

Object.freeze(obj);

// 以下操作都无效
obj.age = 30;        // 无效
obj.city = "北京";   // 无效
delete obj.name;     // 无效

console.log(obj); // { name: "张三", age: 25 }

Object.seal()

javascript
const obj = {
    name: "李四",
    age: 30
};

Object.seal(obj);

// 可以修改现有属性
obj.age = 31;        // 有效

// 但不能添加或删除属性
obj.city = "上海";   // 无效
delete obj.name;     // 无效

console.log(obj); // { name: "李四", age: 31 }

嵌套对象

对象可以包含其他对象:

javascript
const company = {
    name: "科技公司",
    address: {
        street: "长安街100号",
        city: "北京",
        zipCode: "100000"
    },
    employees: [
        {
            name: "张三",
            position: "工程师",
            contact: {
                email: "zhangsan@example.com",
                phone: "13800138000"
            }
        },
        {
            name: "李四",
            position: "设计师",
            contact: {
                email: "lisi@example.com",
                phone: "13900139000"
            }
        }
    ]
};

// 访问嵌套属性
console.log(company.address.city); // "北京"
console.log(company.employees[0].contact.email); // "zhangsan@example.com"

对象的复制

浅拷贝

javascript
const original = {
    name: "张三",
    age: 25,
    hobbies: ["读书", "游泳"]
};

// 使用 Object.assign()
const copy1 = Object.assign({}, original);

// 使用展开运算符(ES6)
const copy2 = { ...original };

// 浅拷贝的问题:嵌套对象仍然是引用
copy1.name = "李四";
copy1.hobbies.push("跑步");

console.log(original.name);    // "张三"(未改变)
console.log(original.hobbies); // ["读书", "游泳", "跑步"](改变了!)

深拷贝

javascript
const original = {
    name: "张三",
    age: 25,
    hobbies: ["读书", "游泳"],
    address: {
        city: "北京",
        street: "长安街"
    }
};

// 使用 JSON 方法(有限制)
const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.name = "李四";
deepCopy.hobbies.push("跑步");
deepCopy.address.city = "上海";

console.log(original.name);     // "张三"(未改变)
console.log(original.hobbies);  // ["读书", "游泳"](未改变)
console.log(original.address.city); // "北京"(未改变)

// 注意:JSON 方法不能复制函数、undefined、Symbol 等

对象的合并

javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { c: 5, d: 6 };

// 使用 Object.assign()
const merged1 = Object.assign({}, obj1, obj2, obj3);
console.log(merged1); // { a: 1, b: 3, c: 5, d: 6 }

// 使用展开运算符
const merged2 = { ...obj1, ...obj2, ...obj3 };
console.log(merged2); // { a: 1, b: 3, c: 5, d: 6 }

对象的解构

javascript
const person = {
    name: "张三",
    age: 25,
    city: "北京",
    job: "工程师"
};

// 基本解构
const { name, age } = person;
console.log(name); // "张三"
console.log(age);  // 25

// 重命名变量
const { name: fullName, age: years } = person;
console.log(fullName); // "张三"
console.log(years);    // 25

// 默认值
const { name: n, salary = 5000 } = person;
console.log(n);      // "张三"
console.log(salary); // 5000

// 嵌套解构
const company = {
    name: "科技公司",
    address: {
        city: "北京",
        street: "长安街"
    }
};

const { address: { city } } = company;
console.log(city); // "北京"

对象的计算属性名

javascript
const propertyName = "dynamicProperty";
const value = "动态值";

// ES6 计算属性名
const obj = {
    [propertyName]: value,
    [1 + 2]: "计算结果"
};

console.log(obj.dynamicProperty); // "动态值"
console.log(obj[3]);              // "计算结果"

对象的方法

Object.keys()、Object.values()、Object.entries()

javascript
const person = {
    name: "张三",
    age: 25,
    city: "北京"
};

console.log(Object.keys(person));    // ["name", "age", "city"]
console.log(Object.values(person));  // ["张三", 25, "北京"]
console.log(Object.entries(person)); // [["name", "张三"], ["age", 25], ["city", "北京"]]

Object.hasOwnProperty()

javascript
const person = {
    name: "张三",
    age: 25
};

console.log(person.hasOwnProperty("name"));     // true
console.log(person.hasOwnProperty("toString")); // false

Object.is()

javascript
console.log(Object.is(1, 1));        // true
console.log(Object.is(0, -0));       // false
console.log(Object.is(NaN, NaN));    // true
console.log(Object.is(null, null));  // true

实际应用示例

javascript
// 用户管理系统
const userSystem = {
    users: [],
    
    addUser(user) {
        this.users.push({
            id: Date.now(),
            ...user,
            createdAt: new Date()
        });
    },
    
    findUserById(id) {
        return this.users.find(user => user.id === id);
    },
    
    updateUser(id, updates) {
        const user = this.findUserById(id);
        if (user) {
            Object.assign(user, updates);
            return user;
        }
        return null;
    },
    
    deleteUser(id) {
        const index = this.users.findIndex(user => user.id === id);
        if (index !== -1) {
            return this.users.splice(index, 1)[0];
        }
        return null;
    },
    
    listUsers() {
        return this.users.map(user => ({
            id: user.id,
            name: user.name,
            email: user.email
        }));
    }
};

// 使用示例
userSystem.addUser({ name: "张三", email: "zhangsan@example.com" });
userSystem.addUser({ name: "李四", email: "lisi@example.com" });

console.log(userSystem.listUsers());

总结

JavaScript 对象的核心要点:

  1. 创建方式:对象字面量、new Object()、构造函数、Object.create()
  2. 属性访问:点表示法、方括号表示法
  3. 方法定义:普通函数、ES6 简写方法
  4. this 关键字:引用调用对象
  5. 遍历方式:for...in、Object.keys()、Object.values()、Object.entries()
  6. 属性控制:属性描述符、冻结、密封
  7. 复制操作:浅拷贝、深拷贝
  8. 现代特性:解构、展开运算符、计算属性名

对象是 JavaScript 编程的基础,掌握对象的使用对于编写复杂的 JavaScript 应用至关重要。在下一章节中,我们将学习 JavaScript 的条件语句。

本站内容仅供学习和研究使用。