JavaScript 原型与继承机制详解

作者:代码拾荒

时间:2026-10-24

浏览:548

本文深入解析 JavaScript 的原型与继承机制,阐述对象如何通过 prototype 属性共享属性和方法。通过 Circle 类与 String 原型扩展等实例,演示构造函数、原型方法定义及属性遮蔽原理,帮助开发者优化内存使用并掌握 JS 面向对象编程核心。

文章目录

JavaScript 原型与继承基础

JavaScript 中的对象通过其原型对象(prototype object)来继承属性。每个对象都拥有原型,且原型的属性在表现上等同于使用该原型作为源的对象属性。简而言之:

所有对象均从其原型继承属性。。

每个对象都从其原型继承属性。



对象的 prototype 属性由构造函数(constructor function)定义。在 JavaScript 中,所有函数都具备一个 prototype 属性,该属性初始为空。随后向此属性添加的任何属性,都将被由该构造函数创建的对象所拥有。



prototype 对象与构造函数紧密关联,这使其成为存放方法及其他常量的理想位置。需要注意的是,原型中的属性并不会被复制到新创建的对象实例中,它们仅在外观上表现为对象的属性。这种机制显著减少了多个同类对象实例所占用的内存空间。



原型属性的读写与遮蔽机制

每个类仅对应一个 prototype 对象,其中附带一套属性。然而,在运行时我们可能会创建该类的多个实例。此时,如果对原型中的属性进行读写操作,会发生什么情况?


当读取属性时,JavaScript 首先检查对象本身是否拥有该属性;若未找到,则继续查找原型中是否存在。若原型中存在,则返回该值。


当尝试写入原型属性时,由于多个对象共享同一原型,直接修改原型并非最佳实践。此时,JavaScript 会在当前对象上创建一个同名的属性,并将值写入该新属性中。下次读取此属性时,JavaScript 会直接在对象自身属性中找到它,从而无需再查询原型。这种现象被称为“对象的属性掩盖或隐藏了原型的属性”(shadows or hides)。



基于上述讨论,在设计类时只需遵循一个核心原则:

在原型中仅定义方法(通常方法是不变的)、常数或常量。

遵循这一原则即可避免混淆。


Circle 类原型定义示例

具体示例如下:



JavaScript 原型与继承基础// Define a constructor method for our class.
JavaScript 原型与继承基础// Use it to initialize properties that will be different for
JavaScript 原型与继承基础// each individual Circle object.
JavaScript 原型与继承基础functionCircle(x, y, r)
JavaScript 原型与继承基础{
JavaScript 原型与继承基础    this.x = x;  // The X-coordinate of the center of the circle
JavaScript 原型与继承基础
this.y = y;  // The Y-coordinate of the center of the circle
JavaScript 原型与继承基础
this.r = r;  // The radius of the circle
JavaScript 原型与继承基础}
JavaScript 原型与继承基础
JavaScript 原型与继承基础
JavaScript 原型与继承基础// Create and discard an initial Circle object.
JavaScript 原型与继承基础// This forces the prototype object to be created in JavaScript 1.1.
JavaScript 原型与继承基础new Circle(0,0,0);
JavaScript 原型与继承基础
JavaScript 原型与继承基础
JavaScript 原型与继承基础// Define a constant: a property that will be shared by
JavaScript 原型与继承基础// all circle objects. Actually, we could just use Math.PI,
JavaScript 原型与继承基础// but we do it this way for the sake of instruction.
JavaScript 原型与继承基础Circle.prototype.pi =
3.14159;
JavaScript 原型与继承基础
JavaScript 原型与继承基础
JavaScript 原型与继承基础// Define a method to compute the circumference of the circle.
JavaScript 原型与继承基础// First declare a function, then assign it to a prototype property.
JavaScript 原型与继承基础// Note the use of the constant defined above.
JavaScript 原型与继承基础function Circle_circumference( ) { return
2
*
this.pi *
this.r; }
JavaScript 原型与继承基础Circle.prototype.circumference =Circle_circumference;
JavaScript 原型与继承基础
JavaScript 原型与继承基础
JavaScript 原型与继承基础// Define another method. This time we use a function literal to define
JavaScript 原型与继承基础// the function and assign it to a prototype property all in one step.
JavaScript 原型与继承基础Circle.prototype.area =
function(  ) { return
this.pi *
this.r *
this.r; }
JavaScript 原型与继承基础
JavaScript 原型与继承基础
JavaScript 原型与继承基础// The Circle class is defined.
JavaScript 原型与继承基础// Now we can create an instance and invoke its methods.
JavaScript 原型与继承基础var c =
new Circle(0.0, 0.0, 1.0);
JavaScript 原型与继承基础var a =c.area( );
JavaScript 原型与继承基础var p = c.circumference( );


内置类的原型扩展

内置类的 prototype 属性。



不仅用户自定义的类拥有 prototype,系统内置类如 String、Date 等也具备此属性。此外,我们还可以向这些内置类添加新的方法或属性。


以下代码展示了如何为所有 String 对象添加一个实用的函数:



JavaScript 原型与继承基础// Returns true if the last character is c
JavaScript 原型与继承基础String.prototype.endsWith =
function(c) {
JavaScript 原型与继承基础    return (c ==
this.charAt(this.length-1))
JavaScript 原型与继承基础}


随后,我们可以像这样调用该函数:



JavaScript 原型与继承基础var message =
"hello world";
JavaScript 原型与继承基础message.endsWith('h')  // Returns false
JavaScript 原型与继承基础message.endsWith('d')  // Returns true

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章