JavaScript面向对象编程:原型与类的区别

作者:木棉

时间:2026-10-22

浏览:70

本文解析JavaScript面向对象编程的核心机制,指出其不同于Java或C#的类概念,而是基于原型(prototype)实现。通过具体示例说明如何创建实例、修改原型指向以及利用Object.create()安全构建对象,帮助开发者掌握JS中继承与多态的真实运作方式。

文章目录

JavaScript面向对象编程基础

在JavaScript中,所有数据本质上都是对象。这是否意味着我们已经在进行面向对象编程?

答案是否定的。如果仅仅使用Number、Array、String以及通过{...}语法定义的基础对象,并不能真正发挥面向对象编程的优势。

JavaScript的面向对象模式与Java、C#等主流语言存在显著差异。对于熟悉Java或C#的开发者而言,理解以下两个核心概念至关重要:

1. 类(Class):类是对象的类型模板。例如,定义Student类代表学生类型,它定义了类型规范,但并不对应任何具体的学生个体。

2. 实例(Instance):实例是根据类创建的具体对象。例如,基于Student类可以生成xiaoming、xiaohong、xiaojun等多个实例,每个实例代表一个具体的学生,且均属于Student类型。

因此,类和实例是大多数面向对象编程语言的基础概念。

原型机制与类概念的区别

然而,在JavaScript中,这一概念需要调整。JS不严格区分类与实例,而是通过原型(prototype)机制来实现面向对象编程。

基于原型的对象创建与继承

当我们希望创建名为xiaoming的具体学生对象时,实际上并不存在一个预定义的Student类。此时,我们可以利用现有的对象作为基础。


var robot = {
 name: 'Robot',
 height: 1.6,
 run: function () {
  console.log(this.name + ' is running...');
 }
};

观察这个robot对象,它拥有name和height属性,并具备run()方法,这与xiaoming的特征相似。我们可以直接基于该对象来“创建”xiaoming。

我们将该对象重命名为Student,并基于它创建xiaoming实例。


var Student = {
 name: 'Robot',
 height: 1.2,
 run: function () {
  console.log(this.name + ' is running...');
 }
};
var xiaoming = {
 name: '小明'
};
xiaoming.__proto__ = Student;

关键步骤在于最后一行代码:将xiaoming的原型指向Student对象。这使得xiaoming看起来像是从Student继承而来。


xiaoming.name; // '小明'
xiaoming.run(); // 小明 is running...

虽然xiaoming自身没有定义run()方法,但由于其原型链指向Student,且Student包含run()方法,因此xiaoming可以直接调用该方法。

JavaScript面向对象编程基础

JavaScript的原型链与Java的Class机制根本不同:JS没有“类”的概念,所有对象均为实例。所谓的继承,仅仅是将一个对象的原型指向另一个对象。

动态修改原型与最佳实践

如果将xiaoming的原型重新指向其他对象,其行为将随之改变。


var Bird = {
 fly: function () {
  console.log(this.name + ' is flying...');
 }
};
xiaoming.__proto__ = Bird;

此时,xiaoming无法再调用run()方法,其行为特征已转变为类似Bird。


xiaoming.fly(); // 小明 is flying...

在JavaScript代码运行期间,你可以动态地将xiaoming的原型从Student切换为Bird,或指向任何其他对象。

上述代码仅用于演示原理。在实际开发中,不应直接使用obj.__proto__修改对象原型,且低版本IE浏览器不支持该属性。推荐使用Object.create()方法,它接受一个原型对象并返回基于该原型的新对象。由于新对象初始为空,我们可以封装一个函数来创建如xiaoming这样的实例。


// 原型对象:
var Student = {
 name: 'Robot',
 height: 1.2,
 run: function () {
  console.log(this.name + ' is running...');
 }
};
function createStudent(name) {
 // 基于Student原型创建一个新对象:
 var s = Object.create(Student);
 // 初始化新对象:
 s.name = name;
 return s;
}
var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章