JavaScript 类和对象详解

JavaScript 类和对象详解

JavaScript 是一种基于原型的面向对象语言,同时也支持基于类的面向对象编程(ES6引入)。以下是 JavaScript 中类和对象的全面介绍:


一、对象基础

1. 对象字面量(最常用)

const person = {
  name: "张三",
  age: 30,
  greet() {
    console.log(`你好,我是${this.name}`);
  }
};

person.greet(); // 输出:你好,我是张三

2. 属性访问

// 点表示法
console.log(person.name);

// 方括号表示法(适用于动态属性名)
const propName = 'age';
console.log(person[propName]);

3. 动态添加/删除属性

// 添加属性
person.job = "工程师";

// 删除属性
delete person.age;

二、构造函数(ES5方式)

1. 基本构造函数

function Person(name, age) {
  this.name = name;
  this.age = age;
  
  this.greet = function() {
    console.log(`你好,我是${this.name}`);
  };
}

const person1 = new Person("李四", 25);
person1.greet();

2. 使用原型共享方法

function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 方法定义在原型上,所有实例共享
Person.prototype.greet = function() {
  console.log(`你好,我是${this.name}`);
};

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

三、ES6 类(语法糖,底层仍基于原型)

1. 基本类定义

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  
  greet() {
    console.log(`你好,我是${this.name}`);
  }
}

const person1 = new Person("赵六", 32);
person1.greet();

2. 静态方法和属性

class Person {
  static species = "人类"; // 静态属性(ES2022)
  
  constructor(name) {
    this.name = name;
  }
  
  static createAnonymous() { // 静态方法
    return new Person("匿名");
  }
}

console.log(Person.species); // "人类"
const anon = Person.createAnonymous();

3. Getter 和 Setter

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  
  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
  
  set fullName(name) {
    [this.firstName, this.lastName] = name.split(' ');
  }
}

const person = new Person("张", "三");
console.log(person.fullName); // "张 三"
person.fullName = "李 四";
console.log(person.firstName); // "李"

四、继承

1. ES6 类继承

class Employee extends Person {
  constructor(name, age, jobTitle) {
    super(name, age); // 调用父类构造函数
    this.jobTitle = jobTitle;
  }
  
  greet() {
    super.greet(); // 调用父类方法
    console.log(`我的职位是${this.jobTitle}`);
  }
}

const emp = new Employee("王五", 35, "经理");
emp.greet();

2. ES5 原型继承

function Employee(name, age, jobTitle) {
  Person.call(this, name, age);
  this.jobTitle = jobTitle;
}

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

Employee.prototype.greet = function() {
  Person.prototype.greet.call(this);
  console.log(`我的职位是${this.jobTitle}`);
};

五、对象高级特性

1. 属性描述符

const obj = {};

Object.defineProperty(obj, 'readOnlyProp', {
  value: 42,
  writable: false,    // 不可写
  enumerable: true,   // 可枚举
  configurable: false // 不可配置
});

obj.readOnlyProp = 100; // 静默失败(严格模式下会报错)
console.log(obj.readOnlyProp); // 42

2. 对象冻结

const obj = { prop: 42 };

Object.freeze(obj); // 冻结对象
obj.prop = 100;    // 静默失败(严格模式下报错)
console.log(obj.prop); // 42

3. 原型链

const arr = [];
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__ === null); // true

六、对象创建模式

1. 工厂模式

function createPerson(name) {
  return {
    name,
    greet() {
      console.log(`我是${this.name}`);
    }
  };
}

2. 构造函数模式

function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log(`我是${this.name}`);
  };
}

3. 原型模式

function Person() {}
Person.prototype.name = "默认";
Person.prototype.greet = function() {
  console.log(`我是${this.name}`);
};

4. 组合模式(构造函数+原型)

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`我是${this.name}`);
};

七、现代 JavaScript 特性

1. 类字段(ES2022)

class Person {
  name = "匿名"; // 实例字段
  static version = "1.0"; // 静态字段
  
  constructor(name) {
    if (name) this.name = name;
  }
}

2. 私有字段和方法(ES2022)

class Person {
  #privateField = "私有"; // 私有字段
  
  #privateMethod() {      // 私有方法
    return this.#privateField;
  }
  
  getPrivate() {
    return this.#privateMethod();
  }
}

const p = new Person();
console.log(p.getPrivate()); // "私有"
console.log(p.#privateField); // 报错

3. 对象解构

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

// 解构赋值
const { name, age } = person;
console.log(name, age); // "张三" 30

// 重命名
const { name: personName } = person;
console.log(personName); // "张三"

// 默认值
const { job = "无" } = person;
console.log(job); // "无"

八、最佳实践

  1. 优先使用 ES6 类:语法更清晰,更接近传统面向对象语言
  2. 遵循单一职责原则:一个类只做一件事
  3. 合理使用继承:避免过深的继承层次,考虑组合优于继承
  4. 封装私有数据:使用私有字段或闭包保护内部状态
  5. 避免过度使用 this:在回调函数中注意 this 的绑定问题
  6. 使用 Object.assign 或展开运算符:进行对象浅拷贝
  7. 考虑使用工厂函数:当不需要复杂继承时

九、示例:完整类实现

class Animal {
  #energy = 0; // 私有字段
  
  constructor(name) {
    this.name = name;
  }
  
  eat(amount) {
    this.#energy += amount;
    console.log(`${this.name} 进食,能量+${amount}`);
  }
  
  move(distance) {
    if (this.#energy >= distance) {
      this.#energy -= distance;
      console.log(`${this.name} 移动了 ${distance}`);
    } else {
      console.log(`${this.name} 能量不足`);
    }
  }
  
  get energy() {
    return this.#energy;
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  
  bark() {
    console.log(`${this.name}${this.breed}): 汪汪!`);
  }
}

const myDog = new Dog("阿黄", "金毛");
myDog.eat(10);
myDog.move(5);
myDog.bark();
console.log(myDog.energy); // 5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值