JavaScript中的继承——笔记
学习文档:MDN web docs —— JavaScript中的继承
目标:理解在JavaScript中如何实现继承。(其实看完了也不一定能理解,没关系,写篇笔记表示我学过)
1. 编写一个Person()构造器
function Person (first, last, age, gender, interests) { this.name = { first, last }; this.age = age; this.gender = gender; this.interests = interests; }
实例方法可定义在Person构造器的原型上,比如:
Person.prototype.greeting = function () { alert('Hi! I\'m ' + this.name.first + '.'); };
2. 现在,我们创建一个Teacher类
让它继承Person的所有成员,并且添加一个新的属性,subject——教师教授的学科,还要一个被更新的greeting方法。
定义Teacher()构造器函数
function Teacher (first, last, age, gender, interests, subject) { Person.call(this, first, last, age, gender, interests); this.subject = subject; }
设置Teacher()的原型和构造器引用
Teacher.prototype = Object.create(Person.prototype);
用create函数来创建一个和Person.prototype一样的新的原型属性值(这个属性指向一个包括属性和方法的对象),这意味着Teacher.prototype现在会继承Person.prototype的所有属性和方法。但是这里有个问题,Teacher.prototype.constructor的值是Person(),这会让人迷惑。可以通过以下代码修改它的值。
Teacher.prototype.constructor = Teacher;
这样就对了。
注:
每一个函数对象(Function)都有一个prototype属性,并且只有函数对象有prototype属性,因为prototype本身就是定义在Function对象下的属性。
当我们输入以下代码来构造对象时
var person1 = new Person(...)
JavaScript实际上参考的是Person.prototype指向的对象来生成person1.
Person()函数是Person.prototype的构造函数,也就是说:
Person === Person.prototype.constructor // true
在定义新的构造函数Teacher时,我们通过Function.call来调用父类的构造函数,但是无法自动指定Teacher.prototype的值。这样Teacher.prototype就只能包含在构造函数里构造的属性,而没有方法。因此我们利用Object.create()方法将Person.prototype作为Teacher.prototype的原型对象,并且改变其构造器指向,使之与Teacher关联
任何你想要被继承的方法都应该定义在构造函数的prototype对象里,并且永远使用父类的prototype来创造子类的prototype,这样才不会打乱继承结构。
向Teacher()添加一个新的greeting()函数
最简单的方法是在Teacher的原型上定义它
Teacher.prototype.greeting = function () { var prefix; if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { prefix = 'Mr.' } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { prefix = 'Mrs.'; } else { prefix = 'Mx.' } alert('Hello, My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); }
3.创建一个Teacher构造函数的实例
var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');
试试这位老师实例的属性和方法
teacher1.name.first; teacher1.interests[0]; teacher1.subject; teacher1.greeting();
4.对象成员总结
你应该基本了解以下三种属性或者方法:
- 那些定义在构造器函数中的、用于给予对象实例的。例如构造函数中使用this.x = x这种。它们是可用于对象实例的成员。
- 那些直接在构造函数上定义、仅在构造函数上可用。
- 那些在构造函数原型上定义、由所有实例和对象类继承的。这些包括在构造函数的原型属性上定义的任何成员。例如myConstructor.prototype.x()
5.何时在JavaScript中使用继承?
- 原型和继承代表了JavaScript这门语言里最复杂的部分。
- JavaScript的强大和灵活性正是来自于它的对象体系和继承方式,这很值得花时间去好好理解下它是如何工作的
- 通常,在小型项目中或者你刚开始学习js的时候,你可能不太需要用到继承。随着代码量的增大,你会发现它的必要性。
- 如果你开始创建一系列拥有相似特性的对象时,那么创建一个包含所有共有功能的通用对象,然后再更特殊的对象类型中继承这些特性,将会变得更加方便有用。
- 在不同对象之间功能的共享通常被叫做委托
- 总之,对象是另一种形式的代码重用。如果你发现自己创建了一堆相关的变量和函数,还想一起追踪它们并将其灵活打包时,对象是个不错的注意。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理