对象

92 阅读3分钟

1、对象的创建

对象字面量

使用{}创建对象

const person = {
  name: "Alice",
  age: 25,
  greet: function() {
    return "Hello, " + this.name;
  }
};

构造对象

使用new Object()创建对象

const person = new Object();
person.name = "Alice";
person.age = 25;
person.greet = function() {
  return "Hello, " + this.name;
};

使用class关键字创建对象

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  greet() {
    return "Hello, " + this.name;
  }
}

const person = new Person("Alice", 25);

2、对象的属性

访问属性

  • 使用点号 . 访问属性。
  • 使用方括号 [] 访问属性(适合动态属性名)
console.log(person.name); // Alice
console.log(person["age"]); // 25

添加属性

直接赋值即可添加属性

person.gender = "female";

删除属性

使用delete删除属性

delete person.age;

检查属性是否存在

使用inhasOwnProperty检查属性是否存在

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

3、对象的遍历

for-in遍历

遍历对象的可枚举属性(包括原型链上的属性)

for (let key in person) {
  console.log(key, person[key]);
}

Object.keys()

获取对象自身的所有可枚举属性

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

Object.values()

获取对象自身的所有可枚举属性值

const values = Object.values(person);
console.log(values); // ["Alice", 25, function]

Object.entries()

获取对象自身的所有键值对

const entries = Object.entries(person);
console.log(entries); // [["name", "Alice"], ["age", 25], ["greet", function]]

4、对象的复制

浅拷贝

使用 Object.assign() 或扩展运算符 ... 进行浅拷贝。

const copy = Object.assign({}, person);
const copy2 = { ...person };

深拷贝

  • 使用 JSON.parse(JSON.stringify(obj)):这是最简单的深拷贝方法,但有以下限制:
    • 不能拷贝函数、undefinedSymbol 等特殊值。
    • 不能处理循环引用(即对象内部引用自身)。
const obj = { name: "John", age: 30 };
const deepCopy = JSON.parse(JSON.stringify(obj));
console.log(deepCopy); // 输出: { name: "John", age: 30 }
  • 递归实现深拷贝(通过递归遍历对象所有的属性,实现更全面的深拷贝)
function deepClone(obj) {
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  const clone = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}

const obj = { name: "John", details: { age: 30 } };
const deepCopy = deepClone(obj);
console.log(deepCopy); // 输出: { name: "John", details: { age: 30 } }
  • 使用递归或第三方库(如 lodash)进行深拷贝。
const deepCopy = JSON.parse(JSON.stringify(person));

深拷贝和浅拷贝的区别

浅拷贝只复制指向某个对象的指针,适用于可迭代对象,新旧对象还是共享同一块内存。深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象

对象的原型

原型链

当你创建一个对象时,这个对象会自动获得一个原型。

每个对象都有一个原型(__proto__),指向其构造函数的 prototype 对象。

console.log(person.__proto__ === Object.prototype); // true

原型链的形成:原型链是由对象的 [[Prototype]] 属性形成的链式结构。每个对象的 [[Prototype]] 属性指向它的原型对象,而原型对象本身也有自己的 [[Prototype]] 属性,这样一直向上直到 null

修改原型

使用 Object.create() 创建对象并指定原型。

const animal = {
  sound: "Unknown",
  makeSound() {
    return this.sound;
  }
};

const dog = Object.create(animal);
dog.sound = "Woof";
console.log(dog.makeSound()); // Woof

6、对象的解构

从对象中提取属性并赋值给变量。

const { name, age } = person;
console.log(name, age); // Alice 25

7、对象的静态方法

Object.keys()

获取对象自身的所有可枚举属性键。

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

Object.values()

获取对象自身的所有可枚举属性值。

const values = Object.values(person);
console.log(values); // ["Alice", 25, function]

** Object.entries()**

获取对象自身的所有键值对。

const entries = Object.entries(person);
console.log(entries); // [["name", "Alice"], ["age", 25], ["greet", function]]

** Object.freeze()**

冻结对象,使其不可修改。

Object.freeze(person);
person.age = 30; // 无效

** Object.seal()**

密封对象,使其不能添加或删除属性,但可以修改现有属性。

Object.seal(person);
person.age = 30; // 有效
person.gender = "female"; // 无效

总结

  • 对象是 JavaScript 的核心数据结构,用于存储键值对。
  • 可以通过对象字面量、构造函数或类创建对象。
  • 对象的属性可以通过点号或方括号访问。
  • 对象的方法是函数属性,可以通过 this 访问对象本身。
  • 使用 for-inObject.keys()Object.values() 和 Object.entries() 遍历对象。
  • 对象的复制分为浅拷贝和深拷贝。
  • 对象的原型和原型链是 JavaScript 继承的基础。
  • ES6 引入了对象解构、属性简写、计算属性名等新特性。