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); // "无"
八、最佳实践
- 优先使用 ES6 类:语法更清晰,更接近传统面向对象语言
- 遵循单一职责原则:一个类只做一件事
- 合理使用继承:避免过深的继承层次,考虑组合优于继承
- 封装私有数据:使用私有字段或闭包保护内部状态
- 避免过度使用 this:在回调函数中注意 this 的绑定问题
- 使用 Object.assign 或展开运算符:进行对象浅拷贝
- 考虑使用工厂函数:当不需要复杂继承时
九、示例:完整类实现
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
1017

被折叠的 条评论
为什么被折叠?



