定制app开发【JS 构造|原型|原型链|继承(圣杯模式)|ES6类语法】下篇

⌚️⌚️⌚️个人格言:定制app开发时间是亳不留情的,定制app开发它真使人在自己制造的定制app开发镜子里照见自己的真相!
📖Git专栏:🔥🔥🔥
📖JavaScript专栏:,定制app开发该专栏持续更新中🔥🔥🔥,定制app开发目的是给大家分享一些定制app开发常用实用技巧,定制app开发同时巩固自己的基础,共同进步,定制app开发欢迎前来交流👀👀👀
👉👉👉定制app开发你的一键三连是对我的最大支持💙 💜 ❤️

文章目录

✔️前言

❗️ ❗️ ❗️本篇系将带来JavaScript中的构造——原型————继承——ES6类语法系列知识完整讲解。 ❗️ ❗️ ❗️
❕上篇涉及:构造——原型——原型链
❕下篇涉及:继承——ES6类语法

🉐内容

📗继承

  • 初认识

此处我们就以通常在各种平台所见到的会员与非会员举例:

  1. 普通会员

属性:用户名、密码

方法:观看免费内容

  1. VIP会员

属性:普通会员的所有属性、会员失效时间

方法:普通会员的所有方法、观看付费内容

如果我们需要使用构造函数来创建会员,如何书写构造函数才能实现上面的需求?

// 普通会员的构造函数function User(loginId, loginPwd) {  this.loginId = loginId;  this.loginPwd = loginPwd;}User.prototype.playFreeContent = function () {  console.log("观看免费内容");};// VIP会员的构造函数function VIPUser(loginId, loginPwd, expires) {  this.loginId = loginId;  this.loginPwd = loginPwd;  this.expires = expires;}VIPUser.prototype.playFreeContent = function () {  console.log("观看免费内容");};VIPUser.prototype.playPaidContent = function () {  console.log("观看付费内容");};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

上面的代码出现了两处重复代码:

  1. VIPUser的构造函数中包含重复代码

    this.loginId = loginId;this.loginPwd = loginPwd;
    • 1
    • 2

    这段代码和User构造函数并没有区别,可以想象得到,将来也不会有区别,即:普通用户该有的属性,VIP用户一定有

  2. VIPUser的原型上包含了重复代码

    VIPUser.prototype.playFreeContent = function () {  console.log("观看免费内容");};
    • 1
    • 2
    • 3

    这个方法和User上的同名方法逻辑完全一致,可以想象得到,将来也不会有区别,即:普通用户该有的方法,VIP用户一定有

如何解决上述两处重复?

  • 处理构造器内部的重复

可以将VIPUser构造器改写为

function VIPUser(username, password, expires){  User.call(this, username, password);  this.expires = expires;}function VIPUser(loginId, loginPwd, expires) {  User.call(this, loginId,loginPwd);  this.expires = expires;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 处理原型上的重复

只需要将原型链设置为下面的结构即可

上面实现仅需一句代码即可:

Object.setPrototypeOf(VIPUser.prototype, User.prototype)
  • 1

至此,完美的解决了之前提到的两处重复代码的问题

  • 这和继承的联系

继承是面向对象的概念,它描述了两个对象类型(类,构造函数)之间的关系

如果在逻辑上可以描述为:A不一定是B,但B一定是A,则:B继承A、A派生B、A是B的父类、B是A的子类。学过后端语言的朋友一定很清楚这是个什么玩意儿

子类的实例应该自动拥有父类的所有成员

JavaScript中,继承具有两个特性:

  1. 单根性:子类最多只有一个父类

  2. 传递性:间接父类的成员会传递到子类中

  • 如何在JS中封装继承?
function inherit(Child, Parent){  // 在原型链上完成继承   Object.setPrototypeOf(Child.prototype, Parent.prototype);}
  • 1
  • 2
  • 3
  • 4

long long ago(开个玩笑啦,也就十多年)…由于没有提供更改隐式原型的方法,因此这一过程会比较复杂。那时候,我们使用一种称之为★圣杯模式★的办法来达到相同的目的,方法如下。

📗伪经典模式/圣杯模式

// 父类function Person(name, age){  this.name = name;  this.age = age;}Person.prototype.sayHello = function(){  console.log("Hello~~");}// 接下来我们要继承了function Student(name, age, gender, score){  // 方法盗用的方式来实现属性的继承(属性)  Person.apply(this,[name, age]);  this.gender = gender;  this.score = score;}// 继承方法Student.prototype = new Person(); // 第一次调用 Person,name 和 age 已经在原型对象上面了var zhangsan = new Student("张三", 24, "男", 99);// 第二次调用 Person,实例对象上面又回存在一份属性console.log(zhangsan.name);console.log(zhangsan.age);console.log(zhangsan.gender);console.log(zhangsan.score);zhangsan.sayHello();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

上面这种方式就是(伪经典模式),但是这种模式也会存在一个缺陷,其缺陷就是属性在实例化对象上面会有一份,在原型对象上面也会有一份,从而造成内存的浪费。

示意图如下:

因此,后面衍生出来了圣杯模式。圣杯模式的核心思想,就是搞一个空函数作为副本。

/** * @param {*} target 子类 * @param {*} origin 父类 */function inherit(target, origin){    function F(){};    F.prototype = origin.prototype;    target.prototype = new F();    target.prototype.constructor = target;}// 父类function Person(name, age){    this.name = name;    this.age = age;}Person.prototype.sayHello = function(){    console.log("Hello~~");}// 接下来我们要继承了function Student(name, age, gender, score){    // 方法盗用的方式来实现属性的继承(属性)    Person.apply(this,[name, age]);    this.gender = gender;    this.score = score;}// 继承方法// Student.prototype = new Person();inherit(Student, Person);var zhangsan = new Student("张三", 24, "男", 99);console.log(zhangsan.name);console.log(zhangsan.age);console.log(zhangsan.gender);console.log(zhangsan.score);zhangsan.sayHello();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

⭐️圣杯模式⭐️示意图如下:

📗类语法

ES6之前,函数有着两种调用方式:

function A(){}A(); // 直接调用new A(); // 作为构造函数调用
  • 1
  • 2
  • 3

这种做法无法从定义上明确函数的用途,因此,ES6推出了一种全新的语法来书写构造函数

示例1:

// 旧的写法function User(firstName, lastName) {  this.firstName = firstName;  this.lastName = lastName;  this.fullName = `${firstName} ${lastName}`;}User.isUser = function () {  console.log("what's up,bro~~");};User.prototype.sayHello = function () {  console.log(`sup, my name is ${this.fullName}`);};// 新的等效写法class User {  constructor(firstName, lastName) {    this.firstName = firstName;    this.lastName = lastName;    this.fullName = `${firstName} ${lastName}`;  }  // 静态方法  static isUser() {    console.log("what's up,bro~~");  }  // 原型方法  sayHello() {    console.log(`sup, my name is ${this.fullName}`);  }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

📌示例1主要演示了新的构造函数创建方式,注意其关键字classconstructorstatic

示例2:

function Animal(type, name){  this.type = type;  this.name = name;}Animal.prototype.intro = function(){  console.log(`I am ${this.type}, my name is ${this.name}`)}function Dog(name){  Animal.call(this, '狗', name);}Dog.prototype = Object.create(Animal.prototype); // 设置继承关系// 新的方式class Animal{  constructor(type, name){    this.type = type;    this.name = name;  }    intro(){    console.log(`I am ${this.type}, my name is ${this.name}`)  }}class Dog extends Animal{ 	constructor(name){    super('狗', name);  }}// 新的设置继承关系方式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

📌示例2主要是为了演示了ES6新的继承方式,注意关键字extendssuper

📕总结

本篇系到此结束,希望各位都有所收获,如有文章有不当之处请在评论区交流,谢谢👋👋👋

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发