滴滴出行网站建设,莫奈设计公司官网,wordpress个人博客系统实现,wordpress 网页制作JS中的OOP
OOP 为我们解决了什么问题#xff1f;想象一下#xff0c;我们希望为教师提供一个平台#xff0c;每位注册的教师都可以提交分数#xff0c;并为课程分配作业和其他内容。
如果有一个地方#xff08;在本例中是一个对象#xff09;#xff0c;可以访问所有教…JS中的OOP
OOP 为我们解决了什么问题想象一下我们希望为教师提供一个平台每位注册的教师都可以提交分数并为课程分配作业和其他内容。
如果有一个地方在本例中是一个对象可以访问所有教师的数据例如他们的姓名、职业和班级列表以及前面提到的那些功能那就太好了。简而言之就是将数据和方法封装或者捆绑在一起。
为了实现我们的目的我们创建一个函数来接收教师的数据并返回一个包含这些数据的对象以及每个教师能够执行的方法。
const teacherCreator (name: string, profession: string, classes: string[]) {const newTeacher {};newTeacher.name name;newTeacher.profession profession;newTeacher.classes classes;newTeacher.submitMark function(mark: number, studentId: number) {//....console.log(学生${studentId} 的分数是${mark}。)}newTeacher.assignHomework function(homework: string, classId: number) {// ....}
}这是我们的teacherCreator功能演示。通过这种方式我们实现了数据和方法的封装。但有一个问题值得我们考虑。
内存耗用大
假设我们在有 1000 名教师我们的这些消耗内存方法会在每个教师对象中重复定义。
但是我们只想要一份函数副本。将所有方法都初始化在一个地方并且每当我们尝试调用其中任何一个方法时我们都从那里选择它并避免这种重复这不是更有效吗
我们可以在 JavaScript 中通过多种解决方案完成同样的事情。
方法一工厂函数
我们可以将实现teacherCreator函数的方式更改为
const teacherCreator (name: string, profession: string, classes: string[]) {const newTeacher Object.create(teacherFunctionStore);newTeacher.name name;newTeacher.profession profession;newTeacher.classes classes;// 返回一个对象return newTeacher;
}// 创建一个对象包含所有方法
const teacherFunctionsStore {submitMark: function(mark: number, studentId: number) {//....console.log(学生${studentId} 的分数是${mark}。)},assignHomework: function(homework: string, classId: number) {// ....}
}const teacher1 teacherCreator(Leo, English, [A1-English]);
teacher1.assignHomeWork(do workbook, 10)在上面的代码块中我们不会在每个教师对象上创建这些方法。我们只是有一个地方——另一个对象——来存储所有方法。现在的问题是 JavaScript 如何知道在哪里找到这些方法并执行它们。
JavaScript 如何执行这段代码
下面我们将逐步指导如何在所有方法中执行此代码。一般来说在 JavaScript 中执行时每段代码所发生的情况都是完全相同的。 JavaScript 会在全局内存中看到teacherCreator它将把它创建为一个函数。顺便说一下它不会进入函数内部。接下来它将看到我们的teacherFunctionStore对象并使用其中的方法在全局内存中启动它。代码的下一行是一个名teacher1为的变量它将在全局内存中初始化但尚未设置值。因此JavaScript 将进入teacherCreator执行上下文中的函数内部。在执行上下文内部 -每个函数调用都会创建一个新的执行上下文- 首先是将函数的参数设置在该执行上下文的本地内存中。Object.create()将为我们创建一个空对象。我们已经将teacherFunctionStore 传递给了它因此它将使用该对象__proto__的属性来引用newTeacher对象。该参考在图中用红线突出显示。
const newTeacher Object.create(teacherFunctionStore);然后我们将向对象添加属性并将其返回到全局内存中——设置teacher1的值。
JavaScript 现在如何调用这些方法
现在的问题是teacher1.assignHomework()如何执行。这些方法不在对象本身内。
答案是非常清楚的。当我们调用对象的方法时JavaScript 将首先查看该对象以查找该函数。如果找到它它将执行它。在我们的例子中它在我们的teacher1对象上找不到assignHomework。它应该抛出错误吗当然不是。至少现在还不行。
JavaScript 不会很快放弃。如果属性或方法不在对象本身内部它将在对象的__proto__属性中查找。
我们已经知道我们的对象teacher1会通过__proto__链接到teacherFunctionStoreJavaScript会找到其中的方法并执行它。
方法2构造函数
使用new关键字来实现我们的功能该关键字可以自动为我们完成这些链接工作。
function TeacherCreator(name: string, profession: string, classes: string[]) {this.name name;this.profession profession;this.classes classes;
}TeacherCreator.prototype.submitMark function(mark: number, studentId: number) {//....console.log(学生${studentId} 的分数是${mark}。)
},TeacherCreator.prototype.assignHomework function(homework: string, classId: number) {// ....
}const teacher1 new TeacherCreator(Leo, English, [A1-English]);
teacher1.assignHomeWork(do workbook, 10)TeacherCreator构造函数前面的 new 关键字将为我们自动执行两件事
创建一个新的教师对象返回新创建的教师对象
构造函数如何使用 new 关键字在幕后执行? 第一行是定义TeacherCreator构造函数。JavaScript 中的每个函数也是一个对象。因此这里我们有一个函数-对象组合如上图所示。每当我们想要访问函数部分时我们都使用()符号而对于对象我们使用.符号。在接下来的代码行中我们将在对象TeacherCreator部分的原型对象上设置一些方法而不是其函数内。我们在全局内存中定义一个teacher1常量。在执行上下文中执行函数之前我们不知道它的值。在执行上下文中首先要处理的还是函数参数。new关键字将为我们做的所有事情都以蓝色列出。创建了包含给我们的函数的数据的对象。对象会在new关键字的帮助下自动this设置__proto__为prototype对象。现在this返回的teacher1对象将是最终值并且该执行上下文将被关闭。这里调用我们创建的对象上的方法。JavaScript 将首先查找teacher1对象上的assignHomwork方法。它进入teacher1的__proto__对象但没有找到它但 __proto__链接到prototype对象并在那里找到它并执行该函数。
ES6 class
class关键字语法的作用与前面方法中TeacherCreator构造函数的作用完全相同。然而它给我们带来了编写更快代码的好处并且看起来与其他语言中实现的 OOP 类似。
class TeacherCreator {constructor(name, profession, classes){this.name name;this.profession profession;this.clasess clasess;}// methods that will be accessible in prototype later on:submitMark function(mark: number, studentId: number) {//....console.log(学生${studentId} 的分数是${mark}。)},assignHomework function(homework: string, classId: number) {// ....}
}ES6 类是否改变了迄今为止 OOP 的实现方式
尽管我们的代码现在看起来更加清晰易读但幕后的整个原理仍然是一样的。JavaScript 仍然会为我们的TeacherCreator类创建函数-对象组合。类内部的constructor方法与我们在构造函数方法中的组合中的函数相同。
总之重复相同的过程但变得更加自动化和干净。这是 JavaScript 中 OOP 背后的一般过程基本上是原型继承。