0

0

js怎么让一个对象继承另一个对象

畫卷琴夢

畫卷琴夢

发布时间:2025-08-13 14:45:01

|

1003人浏览过

|

来源于php中文网

原创

在javascript中,让一个对象继承另一个对象的核心方法是建立原型链关系,最推荐的方式是使用object.create()。1. 使用object.create()可直接指定新对象的原型,实现纯净的原型继承,如const student = object.create(person),使student通过[[prototype]]链访问person的属性和方法;2. es6的class语法糖通过extends实现继承,本质仍是原型链,如class dog extends animal,并需在子类constructor中调用super()以正确初始化父类;3. 继承中的常见问题包括原型上引用类型属性被所有实例共享导致的数据污染,解决方法是在构造函数中初始化引用属性;4. this上下文丢失问题常出现在方法作为回调或解构调用时,需通过bind、箭头函数等方式绑定this;5. 原型链性能通常不是瓶颈,现代引擎对属性查找和内存使用有高度优化,深层原型链在实际中罕见且影响微小,而共享原型方法节省内存,提升效率。因此,javascript继承应优先考虑代码清晰与可维护性,合理选择object.create()或class语法,同时规避引用共享和this指向问题,最终实现高效、安全的对象继承。

js怎么让一个对象继承另一个对象

在JavaScript里,让一个对象继承另一个对象,说白了,就是建立一种原型链关系。最直接、也最推荐的方式是利用

Object.create()
,它能为你创建一个新对象,并指定它的原型是谁。当然,现代JS里我们更多会用到
class
语法糖,它背后也是原型继承的逻辑。

js怎么让一个对象继承另一个对象

解决方案

要让一个对象继承另一个对象,最纯粹、最能体现JavaScript原型本质的方法就是

Object.create()
。它接收两个参数:第一个是你希望新对象的原型是谁,第二个是可选的,用于定义新对象自身的属性。

比如,我们有一个

person
对象:

js怎么让一个对象继承另一个对象
const person = {
    name: '张三',
    age: 30,
    greet() {
        console.log(`你好,我是 ${this.name}。`);
    }
};

现在我想创建一个

student
对象,它应该拥有
person
的所有特性,同时还有自己独有的属性,比如
studentId
。我就可以这样做:

const student = Object.create(person);
student.name = '李四'; // 覆盖父级属性
student.studentId = 'S12345';
student.study = function() {
    console.log(`${this.name} 正在努力学习,学号是 ${this.studentId}。`);
};

student.greet(); // 输出:你好,我是 李四。
student.study(); // 输出:李四 正在努力学习,学号是 S12345。
console.log(student.age); // 输出:30 (从person继承而来)

这里

student
对象并没有直接复制
person
的属性,而是通过
Object.create(person)
student
[[Prototype]]
指向了
person
。当访问
student.age
时,如果
student
自身没有这个属性,JavaScript就会沿着原型链向上查找,直到在
person
上找到它。这种方式非常清晰地表达了“基于现有对象创建新对象”的意图,避免了传统构造函数模式中可能出现的
new
关键字带来的理解偏差,因为它不涉及构造函数调用,就是纯粹的原型链接。

js怎么让一个对象继承另一个对象

为什么说原型链是JavaScript继承的基石?

我觉得,理解JavaScript的继承,核心就在于理解原型链。它不像Java或C++那样有类和严格的继承层级,JS更像是搭积木,每个对象都有一个内部的

[[Prototype]]
属性(在旧浏览器中通常可以通过
__proto__
访问,但这不是标准用法,不建议直接操作),这个属性指向它的“父”对象。当你想访问一个对象的某个属性或方法时,如果它自己没有,JS引擎就会沿着这个
[[Prototype]]
链向上找,直到找到或者到达原型链的顶端(
null
)。

这就像一个家族谱系,你问小明他有没有某个技能,他自己没有,就会问他爸爸,爸爸没有就问爷爷,直到家族里某个长辈有这个技能为止。如果都没人有,那就算了,就是

undefined
。这种机制让JavaScript的继承非常灵活,你可以在运行时动态地修改对象的原型,甚至在原型上添加或删除属性和方法,这些改变会立即影响到所有继承自该原型的对象。这也就解释了为什么
Object.create()
如此重要,因为它就是直接操纵这个
[[Prototype]]
链接的工具。它赋予了JS一种非常独特的、基于对象的继承方式,而不是基于类的。

class
语法糖下的继承:更现代的写法有哪些考量?

随着ES6的到来,JavaScript引入了

class
关键字,这让很多从传统面向对象语言背景转过来的人感到亲切。它看起来确实很像Java或C++中的类,有
constructor
,有
extends
,有
super
。但实际上,这只是一个语法糖,它背后依然是原型链那一套。

jspgou网店系统
jspgou网店系统

JSPGOU一直以来都和jeecms、jeebbs一样,是收费软件,但是从2014年7月12日开始,开始jspgou发布第一个免费版,金磊科技承诺:永远不向使用jspgou免费版用户索取任何费用,为免费用户提供更好的技术支持服务,根据用户提出的完善建议快速完善jspgou系统。 jspgou系统使命:做中国最优秀的免费网店系统,让更多的用户了解和使用java产品。 jspgou免费版适用对象:不限

下载
class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        console.log(`${this.name} 发出了声音。`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 调用父类的构造函数
        this.breed = breed;
    }

    bark() {
        console.log(`${this.name} (一只${this.breed}) 汪汪叫!`);
    }
}

const myDog = new Dog('旺财', '金毛');
myDog.speak(); // 输出:旺财 发出了声音。
myDog.bark();  // 输出:旺财 (一只金毛) 汪汪叫!

使用

class
的好处显而易见:代码可读性更高,结构更清晰,更符合传统面向对象的思维习惯。
extends
关键字直接声明了继承关系,
super()
则解决了子类构造函数中调用父类构造函数的问题,确保了父类属性的正确初始化。

不过,这里面也有一些需要注意的地方。比如,在子类的

constructor
中,你必须在访问
this
之前调用
super()
。这是因为
super()
实际上负责了
this
对象的创建和初始化,如果你不先调用它,
this
就不会被正确绑定。另外,尽管
class
看起来是“类”,但它本质上还是函数,
typeof Animal
依然是
"function"
。所以,别被表象迷惑,它只是把原型链的复杂操作封装起来,提供了一个更现代、更易读的接口。对我个人而言,日常开发中我肯定更偏爱
class
,因为它大大提升了团队协作时的代码理解效率,降低了心智负担。

继承中常见的“坑”和性能思考

在JavaScript的继承实践中,确实有一些常见的“坑”和一些性能上的考量,我觉得这些是每个开发者都应该有点概念的。

一个经典的“坑”就是原型上引用类型属性的共享问题。如果你在原型上定义了一个数组或对象,比如:

function Parent() {}
Parent.prototype.colors = ['red', 'blue'];

const child1 = new Parent();
const child2 = new Parent();

child1.colors.push('green');

console.log(child2.colors); // 输出:['red', 'blue', 'green']

看到没?

child1
修改了
colors
child2
也跟着变了。这是因为
colors
数组是所有实例共享的同一个引用。解决办法通常是在构造函数内部初始化这些引用类型属性,让每个实例都有自己独立的副本。

另一个是关于

this
上下文的丢失。当你在类或原型上定义一个方法,然后把它作为回调函数传递出去,或者从对象中解构出来单独调用时,
this
的指向可能会变得不确定,不再指向原来的实例。这通常需要使用
bind()
方法、箭头函数或者在调用时确保
this
的正确绑定。

至于性能,通常情况下,JavaScript引擎(比如V8)对原型链的查找做了大量优化,所以原型链的深度对性能的影响在大多数应用中可以忽略不计。除非你的原型链非常非常深(比如几十层甚至上百层,这在实际开发中几乎不会出现),否则无需过度担心查找性能。相反,原型继承在内存使用上是很有优势的,因为方法和共享属性只存储一份在原型上,所有实例共享它们,这比每个实例都复制一份要节省大量内存。现代JS引擎还会对那些具有相同原型和属性结构的对象进行优化,这被称为“隐藏类”或“形状”,可以进一步提升属性访问的效率。所以,与其担心原型链的性能,不如更关注代码的结构清晰度和可维护性。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

825

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

731

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

396

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

429

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16881

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.4万人学习

MongoDB 教程
MongoDB 教程

共17课时 | 1.7万人学习

C# 教程
C# 教程

共94课时 | 5.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号