javascript如何实现继承_有哪些不同的方式【教程】
发布时间 - 2026-01-30 00:00:00 点击率:次JavaScript继承无统一标准,ES6 class+extends是主流写法,需先调用super();手动操作prototype或Object.setPrototypeOf更底层但易出错;组合优于继承。
JavaScript 实现继承没有单一“标准答案”,关键看目标环境、代码可维护性,以及是否要兼容老版本。ES6 class 语法只是语法糖,底层仍是基于原型链;而手动操作 prototype 或 Object.setPrototypeOf 更贴近本质,也更容易暴露问题。
用 class + extends 是最简明的现代写法
这是目前主流项目首选,语义清晰、支持 super()、能正确处理静态方法和 new.target。
但要注意:必须在子类构造函数中调用 super(),否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this';且 super() 必须在使用 this 前调用。
示例:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须先调用
this.breed = breed;
}
bark() {
console.log(`${this.name} barks`);
}
}
-
extends会自动设置子类的prototype链,并让Dog.prototype.__proto__ === Animal.prototype - 静态方法也会被继承:
Dog.foo()可以访问Animal.foo()(如果定义了) - 不支持多重继承,
extends A, B是语法错误
手动设置 prototype 链是理解继承本质的关键
ES5 及更早环境或想彻底掌控原型关系时,常用 Object.create() 替换子类的 prototype,再补上 constructor 指回自身。
常见错误是直接赋值 Child.prototype = Parent.prototype——这会让两者共享同一原型对象,修改子类方法会意外影响父类。
正确做法:
function Parent(name) {
this.name = name;
}
Parent.prototype.speak = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 继承实例属性
this.age = age;
}
Child.prototype = Object.create(Parent.prototype); // 关键:创建新对象,链接到 Parent 原型
Child.prototype.constructor = Child; // 修复 constructor 指向
Child.prototype.play = function() {
console.log(`${this.name} plays`);
};
-
Parent.call(this, ...)确保子类实例拥有父类初始化的属性(如this.name) -
Object.create(Parent.prototype)创建干净的原型链,避免污染 - 漏掉
constructor = Child会导致new Child().__proto__.constructor === Parent,影响类型判断
用 Object.setPrototypeOf() 动态调整原型(慎用)
这个 API 允许运行时修改对象的 [[Prototype]],适合极少数需要动态继承的场景(比如插件系统、沙箱封装),但性能较差,且无法在旧版 IE 中使用。
它不能替代构造函数继承——只改原型链,不执行父类初始化逻辑,所以仍需显式调用 Parent.call(this)。
示例:
function A() {}
A.prototype.hello = () => 'hi';
function B() {}
const b = new B();
Object.setPrototypeOf(b, A.prototype); // 把 b 的原型设为 A.prototype
console.log(b.hello()); // 'hi'
- 仅影响单个实例,不是整个类;若想批量设置,得对每个实例调用
- V8 引擎会对频繁修改
[[Prototype]]的对象降级为慢对象,影响后续属性访问性能 - 与
class不兼容:用class定义的类,其原型是不可写的(writable: false),强行setPrototypeOf会
静默失败
真正容易被忽略的是:继承只是复用的一种手段,很多场景下组合(composition)比继承更灵活、更易测试。比如把通用行为抽成独立函数或类,通过属性挂载或参数传入,而不是硬套一层 extends。尤其当父类逻辑复杂、生命周期耦合强时,强行继承反而增加调试成本。
# javascript
# es6
# java
# access
# speak
# Object
# 封装
# 父类
# 子类
# 构造函数
# 继承
# class
# 多重继承
# 对象
# constructor
# this
# prototype
# 会报
# 的是
# 这是
# 也会
# 设为
# 仍是
# 会对
# 不支持
# 但要
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在建站之星绑定自定义域名?
Laravel如何实现模型的全局作用域?(Global Scope示例)
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】
免费网站制作appp,免费制作app哪个平台好?
如何在云指建站中生成FTP站点?
Laravel如何实现全文搜索功能?(Scout和Algolia示例)
html如何与html链接_实现多个HTML页面互相链接【互相】
Laravel如何实现事件和监听器?(Event & Listener实战)
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
javascript日期怎么处理_如何格式化输出
如何续费美橙建站之星域名及服务?
香港服务器如何优化才能显著提升网站加载速度?
SQL查询语句优化的实用方法总结
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
zabbix利用python脚本发送报警邮件的方法
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
郑州企业网站制作公司,郑州招聘网站有哪些?
如何用狗爹虚拟主机快速搭建网站?
如何挑选优质建站一级代理提升网站排名?
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】
Laravel如何使用Gate和Policy进行授权?(权限控制)
高防服务器租用指南:配置选择与快速部署攻略
Laravel如何处理表单验证?(Requests代码示例)
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Laravel Fortify是什么,和Jetstream有什么关系
公司网站制作价格怎么算,公司办个官网需要多少钱?
千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】
Laravel Octane如何提升性能_使用Laravel Octane加速你的应用
JavaScript如何实现音频处理_Web Audio API如何工作?
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
jQuery validate插件功能与用法详解
如何在云主机上快速搭建多站点网站?
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
Python正则表达式进阶教程_复杂匹配与分组替换解析
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
如何做网站制作流程,*游戏网站怎么搭建?
Laravel如何优化应用性能?(缓存和优化命令)
android nfc常用标签读取总结
Laravel如何升级到最新版本?(升级指南和步骤)
Laravel如何使用Vite进行前端资源打包?(配置示例)
悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音
Laravel如何实现文件上传和存储?(本地与S3配置)
如何获取上海专业网站定制建站电话?
javascript中闭包概念与用法深入理解
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
如何注册花生壳免费域名并搭建个人网站?
教学论文网站制作软件有哪些,写论文用什么软件
?


