JS-23-原型继承

一、JS的原型继承

在传统的基于Class的语言如Java、C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass。

但是,JavaScript由于采用原型继承,根本不存在Class这种类型。

但是办法还是有的。我们先回顾Student构造函数:

function Student(props) {this.name = props.name || 'Unnamed';
}Student.prototype.hello = function () {alert('Hello, ' + this.name + '!');
}

以及Student的原型链:

现在,我们要基于Student扩展出PrimaryStudent。

1、先定义出PrimaryStudent

function PrimaryStudent(props) {// 调用Student构造函数,绑定this变量:Student.call(this, props);this.grade = props.grade || 1;
}

但是,调用了Student构造函数不等于继承了StudentPrimaryStudent创建的对象的原型是:

new PrimaryStudent() ----> PrimaryStudent.prototype ----> Object.prototype ----> null

必须想办法把原型链修改为:

new PrimaryStudent() ----> PrimaryStudent.prototype ----> Student.prototype ----> Object.prototype ----> null

这样就有继承关系了。新的基于PrimaryStudent创建的对象不但能调用PrimaryStudent.prototype定义的方法,也可以调用Student.prototype定义的方法。

错误的方式:

PrimaryStudent.prototype = Student.prototype;

如果这样的话,PrimaryStudentStudent共享一个原型对象,那还要定义PrimaryStudent干啥?

我们必须借助一个中间对象来实现正确的原型链,这个中间对象的原型要指向Student.prototype。为了实现这一点,参考道爷(就是发明JSON的那个道格拉斯)的代码,中间对象可以用一个空函数F来实现:

        // PrimaryStudent构造函数:function PrimaryStudent(props) {Student.call(this, props);this.grade = props.grade || 1;}// 空函数F:function F() {}// 把F的原型指向Student.prototype:F.prototype = Student.prototype;// 把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype:PrimaryStudent.prototype = new F();// 把PrimaryStudent原型的构造函数修复为PrimaryStudent:PrimaryStudent.prototype.constructor = PrimaryStudent;// 继续在PrimaryStudent原型(就是new F()对象)上定义方法:PrimaryStudent.prototype.getGrade = function () {return this.grade;};PrimaryStudent.prototype.run = function (){console.log(this.name + ' is running.....')}// 创建xiaoming:var xiaoming = new PrimaryStudent({name: '小明',grade: 2});console.log(xiaoming.name); // '小明'console.log(xiaoming.grade); // 2console.log(xiaoming.getGrade());// 2console.log(xiaoming.run());// '小明 is running'

验证原型:

xiaoming.__proto__ === PrimaryStudent.prototype; // true
xiaoming.__proto__.__proto__ === Student.prototype; // true// 验证继承关系:
xiaoming instanceof PrimaryStudent; // true
xiaoming instanceof Student; // true

新的原型链:

 

如果把继承这个动作用一个inherits()函数封装起来,还可以隐藏F的定义,并简化代码:

function inherits(Child, Parent) {var F = function () {};F.prototype = Parent.prototype;Child.prototype = new F();Child.prototype.constructor = Child;
}

此时,代码变成如下所示:

function Student(props) {this.name = props.name || 'Unnamed';
}Student.prototype.hello = function () {alert('Hello, ' + this.name + '!');
}function PrimaryStudent(props) {Student.call(this, props);this.grade = props.grade || 1;
}// 实现原型继承链:
inherits(PrimaryStudent, Student);// 绑定其他方法到PrimaryStudent原型:
PrimaryStudent.prototype.getGrade = function () {return this.grade;
};

二、小结

JavaScript的原型继承实现方式就是:

  1. 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;(PrimaryStudent)

  2. 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;

  3. 继续在新的构造函数的原型上定义新方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/587705.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt编译QScintilla(C++版)过程记录,报错-lqscintilla2_qt5d、libqscintilla2_qt5找不到问题解决

Qt编译QScintilla [C版] 过程记录 本文是编译该 QScintilla 组件库供 QtCreater 开发 C 桌面软件 流程记录一、编译环境 系统: Windows 10Qt:Qt 5.14.2编译套件:MinGW 64Qscintilla:QScintilla_src-2.11.6 二、下载链接 网站链…

HarmonyOS 和 OpenHarmony

HarmonyOS 和 OpenHarmony 支持的 shell 命令不同,因此有时候需要做一做区分,目前有些文档上没有标注,因此可能产生歧义。 HarmonyOS 支持 getprop: getprop hw_sc.build.os.apiversion # 查看API版本OpenHarmony 上支持 param…

STM32FATFS(未完待续)

注意,本博客适合像我一样的小白,会的不多,但是想快速做些东西,不适合会写驱动的大佬。另外,示例代码中的注释有误(从多个项目中移植过来的,未做更改),请不要被误导&#…

基于51单片机的自动化窗户控制系统设计

**单片机设计介绍,基于51单片机的自动化窗户控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的自动化窗户控制系统设计是一个结合了硬件与软件技术的综合性项目。以下是对该设计的概要描述&a…

Github 2024-04-02Python开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-02统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10系统设计指南 创建周期:2507 天开发语言:Python协议类型:OtherStar数量:241693 个Fork数量:42010 次关注人数:241693 人贡献…

Premiere Pro 2024:赋予创意翅膀,让你的视频飞翔 mac/win版

Premiere Pro 2024,作为Adobe旗下的旗舰视频编辑软件,自推出以来,一直在视频制作领域占据着重要的地位。随着技术的不断进步和创新,Premiere Pro 2024为用户带来了前所未有的编辑体验,重新定义了视频制作的标准。 Pre…

基于51单片机的简易计算器设计

1、任务 本课题模拟计算器设计硬件电路采用三部分电路模块构成, 第一部分是键盘模块电路,采用4*4矩阵式键盘作为输入电路; 第二部分是LCD1602液晶显示模块; 第三部分是以51单片机作为控制核心。 软件程序主要由三部分组成&am…

房间预定小程序怎么做_打造用户的专属空间预定小程序

在这个快节奏的时代,人们对于便捷、高效的生活方式有着越来越高的追求。无论是出差、旅行还是日常生活,一个好的住宿环境都是必不可少的。然而,传统的房间预定方式往往让人头疼不已,电话沟通、排队等待、繁琐的手续……这些问题不…

STM32 M3内核寄存器概念

内容主要来自<<M3内核权威指南>> 汇编程序中的最低有效位&#xff08;Least Significant Bit&#xff09;。LSB是二进制数中最右边的位&#xff0c;它代表了数值中的最小单位。在汇编程序中&#xff0c;LSB通常用于表示数据的最小精度或者作为标志位。 ---------…

电子积木方案开发商

东莞市酷得智能科技有限公司电子积木方案开发商 提供消费电子解决方案、提供IC技术支持&#xff0c;全国线上线下服务 积木小车底层驱动开发过程主要涉及到以下几个方面&#xff1a; 首先&#xff0c;需要对小车底盘结构、硬件、模块等有深入的了解。底盘承载着机器人定位、导…

vue + koa + Sequelize + 阿里云部署 + 宝塔:宝塔数据库连接

之前文章已经介绍了宝塔上传前后端代码并部署&#xff0c;不清楚的请看这篇文章&#xff1a; vue koa 阿里云部署 宝塔&#xff1a;宝塔前后端部署 下面是宝塔创建数据库&#xff1a; 我用的 koa Sequelize 连接的数据库&#xff0c;Sequelize 非常适合前端使用&#xf…

Three.js阴影贴图

生成阴影贴图的步骤如下&#xff1a; 从光位置视点&#xff08;阴影相机&#xff09;创建深度图。从相机的角度进行屏幕渲染在每个像素点&#xff0c;将阴影相机的MVP矩阵计算出的深度值与深度图值进行比较如果深度图值较低&#xff0c;则说明该像素点存在阴影 &#xff0c;因…