JavaScript 中的原型与继承
一、从对象说起, 一切皆对象在 JS 中, 几乎所有的东西都是对象, 或者说最终都会指向某个对象. 比如:let arr [1,2,3];console.log(typeof arr);//objectfunctionfoo() {}console.log(typeof foo);//function (但本质上也是对象)简单的对象创建:let person {name:张三,age:25,sayHi:function() {console.log(你好我是 this.name);}};person.sayHi();// 你好, 我是张三但这样有个问题——每次创建新对象都要写一遍所有属性和方法, 太麻烦了! 于是我们有了后面的构造函数. 二、构造函数对象的工厂functionPerson(name, age) {this.name name;this.age age;this.sayHi function() {console.log(你好, 我是 this.name);};}let person1 newPerson(张三,25);let person2 newPerson(李四,30);person1.sayHi();// 你好, 我是张三person2.sayHi();// 你好, 我是李四这里有几个关键点:1. 函数名通常大写开头这是约定俗成的构造函数命名方式2. 使用new关键字调用3. 函数内部使用this来指代新创建的对象当你使用new调用函数时背后发生了这些事:1. 创建一个全新的空对象2. 将这个空对象的__proto__指向构造函数的prototype属性3. 将构造函数中的this绑定到这个新对象4. 执行构造函数中的代码5. 如果构造函数没有显式返回对象则返回这个新对象三、原型登场上面的构造函数方式有个问题——每个实例都会创建自己的方法副本, 浪费内存, 这时候原型(prototype)就派上用场了!什么是原型?每个函数都有一个prototype属性, 它指向一个对象. 当使用这个函数作为构造函数创建实例时, 所有实例都会共享这个原型对象上的属性和方法.改进版的 Person:functionPerson(name, age) {this.name name;this.age age;}// 将方法放在原型上Person.prototype.sayHi function() {console.log(你好我是 this.name);};let person1 newPerson(张三,25);let person2 newPerson(李四,30);console.log(person1.sayHi person2.sayHi);// true - 现在方法是共享的了什么是原型链?当我们访问一个对象的属性时, JavaScript 会:1. 先在对象自身属性中查找2. 如果没找到, 就去对象的__proto__(即构造函数的prototype) 中查找3. 如果还没找到, 就继续往__proto__.__proto__中查找4. 直到找到Object.prototype(最顶层的原型它的__proto__是null)这就是原型链, JavaScript的继承机制.functionPerson() {}Person.prototype.species 人类;let p newPerson();console.log(p.species);//人类 - 从原型上找到的console.log(p.__proto__ Person.prototype);// trueconsole.log(Person.prototype.__proto__ Object.prototype);// trueconsole.log(Object.prototype.__proto__);// null如果对象自身有属性, 就不会去原型上找了:p.species 地球人;console.log(p.species);//地球人 - 自身的属性console.log(Person.prototype.species);//人类 - 原型上的没变delete p.species;console.log(p.species);//人类 - 删除自身属性后又从原型上找到了四、几种继承的方式1)原型链继承:functionParent() {this.parentProp 父类属性;}Parent.prototype.parentMethod function() {console.log(父类方法);};functionChild() {this.childProp 子类属性;}// 关键点: 子类的原型指向父类的实例Child.prototype newParent();let child newChild();console.log(child.childProp);// 子类属性console.log(child.parentProp);// 父类属性-通过原型链找到的child.parentMethod();// 父类方法问题:所有子类实例共享同一个父类实例的属性(如果是引用类型就麻烦了)创建子类实例时无法向父类构造函数传参2)构造函数继承:functionParent(name) {this.name name;this.colors [red,blue];}functionChild(name, age) {Parent.call(this, name);//关键点:在子类构造函数中调用父类构造函数this.age age;}let child1 newChild(张三,25);child1.colors.push(green);let child2 newChild(李四,30);console.log(child2.colors);//[red, blue]-不受child1影响优点:1. 避免了引用类型属性被所有实例共享2. 可以在子类中向父类传参缺点:方法都在构造函数中定义每次创建实例都会创建一遍方法不能继承父类原型上的方法3)组合继承:结合原型链继承和构造函数继承的优点:functionParent(name) {this.name name;this.colors [red,blue];}Parent.prototype.sayName function() {console.log(this.name);};functionChild(name, age) {Parent.call(this, name);//第二次调用Parentthis.age age;}Child.prototype newParent();//第一次调用ParentChild.prototype.constructor Child;//修复constructor指向Child.prototype.sayAge function() {console.log(this.age);};let child1 newChild(张三,25);child1.colors.push(green);child1.sayName();//张三child1.sayAge();//25let child2 newChild(李四,30);console.log(child2.colors);//[red, blue]4)寄生组合继承:functioninheritPrototype(child, parent) {let prototype Object.create(parent.prototype);// 创建父类原型的副本//Object.create 是创建以指定对象为原型的新对象的方法prototype.constructor child;// 修复constructorchild.prototype prototype;// 将副本作为子类的原型}functionParent(name) {this.name name;this.colors [red,blue];}Parent.prototype.sayName function() {console.log(this.name);};functionChild(name, age) {Parent.call(this, name);this.age age;}// 关键: 使用我们封装的inheritPrototype函数inheritPrototype(Child,Parent);Child.prototype.sayAge function() {console.log(this.age);};let child newChild(张三,25);child.sayName();// 张三child.sayAge();// 25优点:1. 只调用一次父类构造函数2. 子类原型上不会有多余的父类属性3. 原型链保持不变五、ES6的classES6 引入了class语法, 让面向对象编程更加直观:classParent {constructor(name) {this.name name;this.colors [red,blue];}sayName() {console.log(this.name);}}classChildextendsParent {constructor(name, age) {super(name);// 必须在使用this之前调用superthis.age age;}sayAge() {console.log(this.age);}}let child newChild(张三,25);child.sayName();// 张三child.sayAge();// 25class本质上仍然是基于原型的语法糖. 上面的代码大致相当于:functionParent(name) {this.name name;this.colors [red,blue];}Parent.prototype.sayName function() {console.log(this.name);};functionChild(name, age) {Parent.call(this, name);this.age age;}Child.prototype Object.create(Parent.prototype);Child.prototype.constructor Child;Child.prototype.sayAge function() {console.log(this.age);};class还提供了静态方法和属性的简洁写法:classMyClass {staticstaticMethod() {console.log(我是静态方法);}static staticProperty 我是静态属性;}MyClass.staticMethod();//我是静态方法console.log(MyClass.staticProperty);//我是静态属性六、其他相关内容instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上.functionmyInstanceof(instance, constructor) {let proto Object.getPrototypeOf(instance);while (proto) {if (proto constructor.prototype) {returntrue;}proto Object.getPrototypeOf(proto);}returnfalse;}console.log([]instanceofArray);// trueconsole.log(myInstanceof([],Array));// true原型可以被修改, 这可能导致安全问题:// 不要这样做Object.prototype.hack function() {console.log(被黑了);};let obj {};obj.hack();// 被黑了

相关新闻

免费解锁Wand游戏修改器高级功能的完整开源解决方案

免费解锁Wand游戏修改器高级功能的完整开源解决方案

免费解锁Wand游戏修改器高级功能的完整开源解决方案 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer 还在为Wand(原WeMod)的…

2026/7/17 23:50:12阅读更多 →
第七史诗智能自动化助手:彻底解放双手的终极游戏伴侣

第七史诗智能自动化助手:彻底解放双手的终极游戏伴侣

第七史诗智能自动化助手:彻底解放双手的终极游戏伴侣 【免费下载链接】e7Helper 【Epic Seven Auto Bot】第七史诗多功能覆盖脚本(刷书签🍃,挂讨伐、后记、祭坛✌️,挂JJC等📛,多服务器支持📺&a…

2026/7/17 23:50:12阅读更多 →
亚洲EMBA怎么选?2026民企老板择校性价比实测榜单

亚洲EMBA怎么选?2026民企老板择校性价比实测榜单

【客观测评声明】本文为独立财经测评内容,无硬性品牌营销导向,基于2026年亚洲主流EMBA项目公开数据,从民企实业经营视角,客观拆解各项目适配度、优势与短板,为企业创始人、高管提供理性择校参考,规避择校踩…

2026/7/17 23:50:12阅读更多 →
Avocado-VT核心功能揭秘:Cartesian Config参数配置终极教程

Avocado-VT核心功能揭秘:Cartesian Config参数配置终极教程

Avocado-VT核心功能揭秘:Cartesian Config参数配置终极教程 【免费下载链接】avocado-vt Avocado-VT is a compatibility plugin that lets you execute virtualization related tests, with all conveniences provided by Avocado 项目地址: https://gitcode.com…

2026/7/18 0:45:22阅读更多 →
Python阶乘函数,一行代码算尽天下

Python阶乘函数,一行代码算尽天下

编写n的阶乘一个整数的阶乘, 是所有小于, 并且等于该数字的正整数的乘积, 举例来讲, 3的阶乘, 是3乘以2乘以1。在成都, 存在着一条创新互联联系热线, 它能够为您给予成都网站建设、网页设计以及定制高端网站建设方面的服务, 于成都创新互联网页制作这个领域历经了十余年, 在涵盖…

2026/7/18 0:45:22阅读更多 →
计算机毕业设计之jsp智慧采摘园管理系统的设计和实现

计算机毕业设计之jsp智慧采摘园管理系统的设计和实现

随着世界经济信息化、全球化的到来和互联网的飞速发展,推动了各行业的改革。若想达到安全,快捷的目的,就需要拥有信息化的组织和管理模式,建立一套合理、动态的、交互友好的、高效的智慧采摘园管理系统。当前的信息管理存在工作效…

2026/7/18 0:45:22阅读更多 →
计算机毕业设计之jsp志愿者服务管理系统设计与实现

计算机毕业设计之jsp志愿者服务管理系统设计与实现

伴随着社会以及科学技术的发展,互联网已经渗透在人们的身边,网络慢慢的变成了人们的生活必不可少的一部分,紧接着网络飞速的发展,系统管理这一名词已不陌生,越来越多的志愿者服务等机构都会定制一款属于自己个性化的管…

2026/7/18 0:45:22阅读更多 →
罗德与施瓦茨HMP4040四通道高性能可编程线性直流电源

罗德与施瓦茨HMP4040四通道高性能可编程线性直流电源

罗德与施瓦茨HMP4040四通道高性能可编程线性直流电源 罗德与施瓦茨HMP4040是一款四通道高性能可编程线性直流电源,广泛应用于工业测试与实验室研发场景。它由德国Hameg(惠美)公司推出,属于R&S HMP4000系列的旗舰型号&#xff…

2026/7/18 0:45:22阅读更多 →
033-Preferences键值存储

033-Preferences键值存储

Preferences 键值存储 — 轻量级配置数据的持久化方案 一、引言 在应用开发中,大量的配置类数据(如用户偏好、开关状态、简单缓存)不需要复杂的数据库支持,只需要一个轻量级的键值存储方案。鸿蒙系统的 Preferences(…

2026/7/18 0:40:22阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/17 10:42:55阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/17 8:31:03阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/17 13:22:23阅读更多 →
从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则

从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则

更多请点击: https://kaifayun.com 第一章:从模糊意图到可执行指令:Claude PRD中Prompt Engineering与需求颗粒度的5级映射法则 在Claude驱动的产品需求文档(PRD)生成实践中,原始业务意图往往以自然语言片…

2026/7/18 0:00:14阅读更多 →
Cursor配置生成失效?3大隐藏陷阱+4行修复代码,资深工程师连夜整理的紧急补救清单

Cursor配置生成失效?3大隐藏陷阱+4行修复代码,资深工程师连夜整理的紧急补救清单

更多请点击: https://codechina.net 第一章:Cursor配置生成失效?3大隐藏陷阱4行修复代码,资深工程师连夜整理的紧急补救清单 Cursor 配置生成突然失效,是近期高频报障场景。表面看是 cursor.config.json 未更新或 LSP…

2026/7/18 0:00:14阅读更多 →
某智驾大牛创业

某智驾大牛创业

作者:钟声编辑:Mark出品:红色星际头图:智能驾驶图片据悉,国内某头部智驾公司端到端模型技术大牛Z投身创业,并且已经拿到融资。Z不仅是该头部公司内部最年轻的对标阿里P10级别技术负责⼈,更是业内…

2026/7/18 0:00:14阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/17 22:48:46阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/17 13:22:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/17 17:26:50阅读更多 →