JavaScript 中的原型与继承 - JavaScript学习系列文章

发布时间:2026/8/25 11:55:06

JavaScript 中的原型与继承 - 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();// 被黑了

相关新闻

开源考试系统本地部署实战:从环境配置到联调排坑全指南

开源考试系统本地部署实战:从环境配置到联调排坑全指南

2026/8/25 11:55:06

1. 项目缘起:为什么要在本地折腾一个开源考试系统?如果你是一名开发者、教育技术从业者,或者是一个小团队的负责人,想搭建一个在线考试平台,大概率会先想到去网上找现成的开源项目。这个想法很对,毕竟从头造…

Python标准库:开箱即用的生产级工具箱与工程实践指南

Python标准库:开箱即用的生产级工具箱与工程实践指南

2026/8/25 11:45:06

1. 什么是Python标准库:不是“第三方”,而是你装完Python就自带的“出厂配置” 很多人第一次听说“Python标准库”,下意识会把它和pip install安装的requests、numpy、pandas混为一谈——这其实是个根本性误解。Python标准库(Pyt…

TVA-World生成式具身智能:概念、原理、应用(1)

TVA-World生成式具身智能:概念、原理、应用(1)

2026/8/25 11:45:06

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的系统级视觉技术框架。它融合深度强化学习(DRL)、卷积神…

Python从零到一:基础语法趣味入门指南

Python从零到一:基础语法趣味入门指南

2026/8/25 12:35:08

在当前 AI 大环境下,Python 语言在编程语言中的比重大幅增长,学习 Python 语言已经成为做 AI 应用开发的重要前置条件。学习 Python 语言就从此刻开始,随我来一起学习了解一下它吧。本文从 Python 语言的基础语法使用开始介绍,逐步…

零基础搭建《我的世界》基岩版私人服务器:从局域网到公网联机全攻略

零基础搭建《我的世界》基岩版私人服务器:从局域网到公网联机全攻略

2026/8/25 12:35:08

想和三五好友一起在《我的世界》基岩版里建造、冒险,却苦于找不到稳定、免费的服务器?或者觉得租用服务器太麻烦、太贵?其实,你完全可以用自己的电脑搭建一个专属的私人服务器!无论是宿舍局域网,还是天南海…

零成本搭建《我的世界》基岩版服务器:从本地部署到外网联机全攻略

零成本搭建《我的世界》基岩版服务器:从本地部署到外网联机全攻略

2026/8/25 12:35:08

这次我们来看一个非常实际的需求:如何在自己的电脑上搭建一个《我的世界》基岩版服务器,实现和朋友联机。很多玩家想和朋友一起玩,但不想租用昂贵的服务器,或者只是想临时开个服体验一下。其实,用你自己的电脑就能搞定…

数据加解密基础知识

数据加解密基础知识

2026/8/25 12:35:08

文章目录数据加解密基础知识笔记为什么要做数据加解密几个必须区分的基础概念加密算法的三大分类对称加密什么是对称加密常见对称加密算法对称加密的优点对称加密的缺点常见使用场景非对称加密什么是非对称加密常见非对称加密算法非对称加密的优点非对称加密的缺点常见使用场景…

仓储货架对楼面载荷怎么算?一个公式搞定(附计算实例)

仓储货架对楼面载荷怎么算?一个公式搞定(附计算实例)

2026/8/25 12:35:08

仓储货架对楼面载荷怎么算?一个公式搞定(附计算实例) 文章目录仓储货架对楼面载荷怎么算?一个公式搞定(附计算实例)前言一、先搞清楚两个概念:平均载荷 vs 集中载荷二、立柱集中载荷计算公式三、…

基于AI大模型的JSON文件高质量汉化实战:告别垃圾机翻

基于AI大模型的JSON文件高质量汉化实战:告别垃圾机翻

2026/8/25 12:25:08

大家好,我是专注于分享实用开发技巧的技术博主。在日常开发或使用各类软件、工具时,我们经常会遇到需要汉化 JSON 配置文件、语言包或插件的情况。传统的汉化工具(如一些自动化脚本或早期工具)往往依赖简单的机器翻译,…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/24 19:53:32

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/24 19:56:07

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/24 21:16:09

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南

2026/8/25 0:04:34

三步把QQ空间历史说说导出到本地:GetQzonehistory 极简指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory Meta Description:GetQzonehistory 是一个QQ空间历史说…

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

洛谷 P7912:[CSP-J 2021 T4] 小熊的果篮 ← 双向链表

2026/8/25 0:04:35

【题目来源】 https://www.luogu.com.cn/problem/P7912 【题目描述】 小熊的水果店里摆放着一排 n 个水果。每个水果只可能是苹果或桔子,从左到右依次用正整数 1,2,…,n 编号。连续排在一起的同一种水果称为一个“块”。小熊要把这一排水果挑到若干个果篮里&#x…

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG

2026/8/25 0:04:35

Transformers.js 网页端图像抠图实战:零后端 3 行代码返回透明 PNG 【免费下载链接】transformers.js State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server! 项目地址: https:/…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/22 4:13:47

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/22 1:32:34

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…