8. JavaScript 对象操作知多少?

91 阅读4分钟

JavaScript 对象操作知多少?

在 JavaScript 中,对象 是一个非常核心的 数据类型。对象 用于 存储一组 具有相关属性 和 方法 的数据,通常以 键值对 的形式 组织数据

1 创建对象

1.1 字面量 {} 方式

通过 对象字面量,你可以 直接创建 一个对象,并为其 指定 属性方法,而无需使用 构造函数 或 类

// 示例代码 1
const person = {
    name: "Alice",
    age: 25,
    greet: function() {
        console.log("Hello!");
    }
};

1.2 使用 new Object()

// 示例代码 2
const person = new Object();
person.name = "Alice";
person.age = 25;
person.greet = function() {
    console.log("Hello!");
};

这种方式比较冗长,不常用,因为对象字面量更简洁。

2 访问和修改对象的属性

2.1 点语法(Dot Notation)

使用 . 来 访问 或 修改 对象的 属性。

// 示例代码 3
console.log(person.name);  // 输出 Alice
person.age = 26;  // 修改属性
console.log(person.age);  // 输出 26

2.2 方括号语法(Bracket Notation)

如果 属性名动态的(例如由 变量表达式计算 得到),或者 属性名 包含 空格 或 其他 特殊字符,方括号语法 是 必需的。

属性名是动态的
// 示例代码 4
const key = "age";
const person = {
  name: "Alice",
  [key]: 30 // 使用变量 `key` 作为属性名
};

console.log(person.age); // 输出:30

在这个例子中,key 变量的值 "age" 被用作 person 对象的 属性名。

属性名包含空格
// 示例代码 5
const person = {
  "first name": "John", // 属性名包含空格
  "last name": "Doe"
};

console.log(person["first name"]); // 输出:John
console.log(person["last name"]);  // 输出:Doe
属性名包含特殊字符
// 示例代码 6
const person = {
  "@username": "alice123",  // 属性名包含特殊字符 "@"
  "123name": "Bob"          // 属性名以数字开头
};

console.log(person["@username"]); // 输出:alice123
console.log(person["123name"]);  // 输出:Bob

3 对象的方法

对象的方法 是定义在 对象内部 的函数。它们通常用于 操作对象的属性执行与对象相关的行为

// 示例代码 7
const person = {
    name: "Alice",
    age: 25,
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

person.greet();  // 输出 Hello, my name is Alice

this 关键字 指向 调用该方法的 对象,在这里指向 person

简化方法定义(ES6)

ES6 引入了简化方法定义的语法,可以 省略 function 关键字

// 示例代码 8
const person = {
    name: "Alice",
    age: 25,
    greet() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

person.greet();  // 输出 Hello, my name is Alice

4 遍历对象属性的几种方式

以下是 遍历对象属性

4.1 for...in 循环

for...in 循环 用于 遍历对象 的 所有 可枚举属性(包括 继承的 属性)。可以使用 hasOwnProperty 方法 来 检查 属性 是否是 对象本身的

// 示例代码 9
for (let key in person) {
    console.log(key, person[key]);
}
// 输出:
// name Alice
// age 25
// greet [Function: greet]

4.2 Object.keys()

Object.keys() 方法 返回一个 包含 对象所有 自有非继承属性名数组

// 示例代码 10
console.log(Object.keys(person));  // 输出 ["name", "age", "greet"]

4.3 Object.values()

Object.values() 方法 返回一个 包含 对象所有 自有 属性值数组

// 示例代码 11
console.log(Object.values(person));  // 输出 ["Alice", 25, function]

4.4 Object.entries()

Object.entries() 方法 返回一个 包含 键值对数组每个元素一个数组,形式为 [key, value]

// 示例代码 12
console.log(Object.entries(person));  // 输出 [["name", "Alice"], ["age", 25], ["greet", function]]

5 对象的合并与拷贝

5.1 Object.assign()

Object.assign() 方法 用于将 源对象 的 所有 可枚举属性 复制到 目标对象 中。

// 示例代码 13
const person = { name: "Alice", age: 25 };
const contact = { email: "alice@example.com", phone: "123456" };

const combined = Object.assign({}, person, contact);
console.log(combined);
// 输出: { name: 'Alice', age: 25, email: 'alice@example.com', phone: '123456' }

Object.assign()浅拷贝,它会 复制 源对象 的 属性值,但如果 属性值对象,它会 复制引用

5.2 扩展运算符 (...)

ES6 引入了 扩展运算符,可以更加 简洁地 复制合并 对象

// 示例代码 14
const person = { name: "Alice", age: 25 };
const contact = { email: "alice@example.com", phone: "123456" };

const combined = { ...person, ...contact };
console.log(combined);
// 输出: { name: 'Alice', age: 25, email: 'alice@example.com', phone: '123456' }

扩展运算符 也是 浅拷贝

6 this 和 对象

对象的方法的 内部this 指向 调用该方法的 对象

// 示例代码 15
const person = {
    name: "Alice",
    greet() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

person.greet();  // 输出 Hello, my name is Alice

如果在 外部调用方法(而不是 作为对象的方法),this 将指向 全局对象(在浏览器中是 window)。

7 对象的动态属性

对象的属性动态添加删除

// 示例代码 16
// 动态添加属性
person.address = "123 Main St";
console.log(person.address);  // 输出 123 Main St

// 删除属性
delete person.age;
console.log(person.age);  // 输出 undefined

8 Symbol 作为对象的属性

Symbol 是一种 新的 基本数据类型,可以用作 对象属性。它 保证 每个 Symbol 值 都是 唯一的

// 示例代码 17
const person = {
    name: "Alice",
    [Symbol("id")]: 123
};

console.log(person[Symbol("id")]);  // undefined
console.log(person[Object.getOwnPropertySymbols(person)[0]]);  // 输出 123

Symbol("id") 不等于 它本身。这样就可以 用于 定义 唯一的 对象属性,避免 属性名 冲突