首页 > 其他分享 >extends笔记

extends笔记

时间:2023-04-22 19:25:46浏览次数:30  
标签:prototype Parent 继承 笔记 extends Child 父类 构造函数

JavaScript面向对象

继承extends

1. 概念(主要用途)

将子类中的共性代码 ( 属性和方法 ) 抽取出来 放到父类中 每当有一个新的子类需要用到共性的属性或者方法时 不需要在自己内容复写一遍 只需要继承父类的代码


2. 继承的优点与缺点

2.1 优点

  • 实现代码复用 共性代码不需要重写 只需要继承父类即可

  • 提高了代码可维护性 (同时也是缺点) 父类中共性代码改变 子类跟随改变 子类也可以在自己的类中重写共性代码完成自己需求

  • 继承是多态的前提条件 它使得类与类之间产生了联系


2.2 缺点

  • 违反了开发原则(高内聚 低耦合) 类的耦合性增高了

  • 耦合: 类与类之间的联系

  • 内聚: 类独自完成某件事的能力


3. JS继承的方式

注意: 理解new和this是理解继承的前提

3.1 构造函数继承

使用call方法改变父类中的this指向到子类上

function Fn(name1) {
  this.name = name1;
}

function FnSon(name2) {
  Fn.call(this, name2);
  //如果子类中有父类同名属性应写在call下面
}

const fs = new FnSon('bob');
console.log(fs);
// FnSon {name: 'bob'}

特点

  • 写法简易

  • 易于做多继承

  • 只能继承构造函数内的属性和方法 无法继承构造函数原型上面的属性和方法


3.2 原型对象继承

将父类原型Prototype深拷贝给子类原型Prototype

  // 创建父类构造函数
  function Parent(n){
    this.name = n;
  }
  Parent.prototype.show = function(){
    console.log(this.name);
  }

  // 创建子类构造函数
  function Child() {}

  //将父类Prototype内容深拷贝给子类Prototype
  Child.prototype = {
    ...Parent.prototype,
    constructor: Child
    //用这种方法继承会缺失constructor 要自己指明
  }

  Child.prototype.show = function() {
    console.log('hello');
  } // 重写父类中的show方法

特点

  • 只能继承父类构造函数原型上属性和方法 不能继承构造函数内的属性和方法

  • 可以实现多继承


3.3 原型链继承

将子类构造函数的Prototype指向父类实例对象的__proto__

  function Parent(n){
    this.name = n
  }
  Parent.prototype.show = function(){
    console.log(this.name)
  }

  function Child() {}

  // 将父类的实例对象的__proto__给子类的原型
  // 如果父类有参数要传 必须在原型链继承时候就给上实参(不实用)
  Child.prototype = new Parent('hello show');

  // 在继承之前:子类构造函数的Prototype 指向 子类构造函数的Prototype
  // 完成继承之后:子类构造函数的Prototype 指向 父类实例对象的__proto__ 指向 父类构造函数的Prototype

注意: 如果把子类构造函数的Prototype直接指向父类构造函数的Prototype(浅拷贝) 那子类重写父类方法的时 父类跟随一起改变

特点

  • 既能继承构造函数内的属性和方法,又能继承原型上的属性和方法

  • 因为在继承时候就要处理参数 所以不实用

  • 不适合多继承 (原型链多继承需要用B继承A 再用C继承B 这样就可以达到多继承(C继承A和B)目的 但是会增加原型链层级)


3.4 组合(混合)继承

构造继承 + 原型继承/原型链继承

这种方法结合了单个方法的优点

 // 构造继承 + 原型继承
  function Parent(n){
    this.name = n
  }
  Parent.prototype.show = function(){
    console.log(this.name)
  }

  function Child(n){
      //  用构造继承继承父类构造函数中属性和方法
      // 弥补原型继承无法继承构造函数中属性和方法的缺点
    Parent.call(this, n);
  }
  // 用原型继承能继承父类原型中属性和方法优势
  // 弥补构造继承无法继承父类原型中属性和方法的缺点
  Child.prototype = {
    ...Parent.prototype,
    constructor: Child
    //依旧缺少constructor 要自己指明
    //constructor 是用来标记当前Prototype所属函数
  }
 // 构造继承 + 原型链继承

  function Parent(n){
    this.name = n
  }
  Parent.prototype.show = function(){
    console.log(this.name)
  }

  // 用构造继承弥补了原型链继承必须在继承时就传参的缺点
  function Child(n){
    Parent.call(this, n);
  }
  // 用原型链继承能继承父类原型中属性和方法优势
  // 弥补构造继承无法继承父类原型中属性和方法的缺点
  Child.prototype = new Parent();
  Child.prototype.constructor = Child;
  //缺少constructor 要自己指明
  //constructor 是用来标记当前Prototype所属函数

3.5 ES6新增extends继承

使用extends关键字和super(形参)来达到继承

  // ES6创建构造函数
  class Parent{
    constructor(name, age){
      this.name = name;
      this.age = age;
    }
    show(){
      console.log(this.name)
    }
  }
  // ES6extends关键字
  class Child extends Parent{
    constructor(n, a){
      // 父类又称超类
      // super 代表了父类构造函数
      // 但是返回的是子类实例
      // 即 super 内部的 this 指的是子类实例
      // 因此 super(n, a) 在这里相当于 A.prototype.constructor.call(this, n, a)
      // n a对应了父类中的name age
      super(n, a);
    }
    // 重写父类中方法
    show(){
      console.log("重写父类show方法")
    }
  }

注意

  • 如果不写super会报错 父类中没有形参 super()也不用给 super形参和父类一一对应
  • super只能在有extends的子类class中使用

4. 实例和构造函数关系检测

  • 关键字: instanceof

实例对象 instanceof 构造函数

  function Parent(){}

  function Child(){}

  // Child原型链继承parent
  Child.prototype = new Parent();
  
  const p = new Parent();

  const c = new Child();

  console.log( p instanceof Parent );
  // true
  console.log( c instanceof Child );
  // true
  console.log( c instanceof Parent );
  // true Child继承Parent
  console.log( p instanceof Child );
  // false Parent并没有继承Child

  • 原型对象方法: isProtoypeOf()

构造函数.prototype.isPrototypeOf(实例对象)

  function Parent(){}

  function Child(){}

  // Child原型链继承parent
  Child.prototype = new Parent();
  
  const p = new Parent();

  const c = new Child();

  console.log( Parent.prototype.isPrototypeOf( p ) );
  // true
  console.log( Child.prototype.isPrototypeOf( c ) );
  // true
  console.log( Parent.prototype.isPrototypeOf( c ) );
  // true Child继承Parent
  console.log( Child.prototype.isPrototypeOf( p ) );
  // false Parent并没有继承Child

只要实例对象和构造函数存在关系 无论中间隔多少层都 返回true 否则返回false

可以利用这两种方法区分对象 数组 Set Map等

  let arr = [];
  let obj = {};

  console.log(arr instanceof Array)
  // true
  console.log(Array.prototype.isPrototypeOf(arr))
  // true
  console.log(pbj instanceof Array)
  // false
  console.log(Array.prototype.isPrototypeOf(obj))
  // false
  • 万能检测方法

Object.prototype.toString.call()

 Object.prototype.toString.call("hello") 
// [object String]

注意

用instanceof和isPrototypeOf()不能检测undefined和null

这两种数据只能用万能检测法

标签:prototype,Parent,继承,笔记,extends,Child,父类,构造函数
From: https://www.cnblogs.com/SpicyPeper/p/17343716.html

相关文章

  • 计组笔记:第三章 存储系统
    第三章存储系统【复习提示】本章是历年考査的重点,特别是有关Cache和存储器扩展的知识点容易出综合题。此外,存储器的分类与特点,存储器的扩展(芯片选择、连接方式、地址范围等),低位交叉存储器,Cache的相关计算与替换算法,虚拟存储器与快表也容易出选择题。读者应在掌握基本原理和......
  • 计组笔记:第四章 指令系统
    第四章指令系统【复习提示】指令系统是表征一台计算机性能的重要因素。读者应注意扩展操作码技术,各种寻址方式的特点及有效地址的计算,相对寻址有关的计算,CISC与RISC的特点与区别。本章知识点出选择题的概率较大,但也有可能结合其他章节出有关指令的综合题。2014年、2015年已连......
  • 计组笔记:第五章 中央处理器
    第五章中央处理器【复习提示】中央处理器是计算机的中心,也是本书的难点。其中,数据通路的分析、指令执行阶段的节拍与控制信号的安排、流水线技术与性能分析易出综合题。而关于各种寄存器的特点、指令执行的各种周期与特点、控制器的相关概念、流水线的相关概念也极易出选择题......
  • 计组笔记:第六章 总线
    第六章总线【复习提示】本章的知识点较少,其中总线仲裁及总线操作和定时方式是难点。本章内容通常以选择题的形式出现,特别是系统总线的特点、性能指标、各种仲裁方式的特点、异步定时方式及常见的总线标准和特点等。总线带宽的计算也可能结合其他章节出综合题在学习本章时,请读......
  • 计组笔记:第七章 输入/输出系统
    第七章输入/输出系统【复习提示】I/O方式是本章的重点和难点,每年不仅会以选择题的形式考查基本概念和原理,而且可能会以综合题的形式考査,特别是各种IO方式效率的相关计算,中断方式的各种原理、特点、处理过程、中断屏蔽,DMA方式的特点、传输过程、与中断方式的区别等。在学习本......
  • 计组笔记: 第二章 数据的表示与运算
    第二章数据的表示与运算https://i.cnblogs.com/posts/edit;postId=-1;templateId=811【复习提示】本章内容较为繁杂,由于计算机中数的表示和运算方法与人们日常生活中的表示和运算方法不同,因此理解也较为困难。纵观近几年的真题,不难发现unsigned、shot、int、long、foat、......
  • 【OMNET++网络仿真系列学习笔记-1】Ubuntu 22.04版本安装OMNET++6.0版本及各类报错合
    本章目录前言第一步:下载6.0压缩包第二步:解压并安装第三步:启动环境变量第四步:遇到的问题第五步:./configure编译结束第六步:验证安装是否可以正常运行?第七步:验证IDE总结:写在后面的话前言本篇文章记录了22.04版本Ubuntu安装OMNET++6.0版本及各类报错合集解决方案,途中遇到了无数问题,很......
  • (2023)Admob广告实践笔记
    开屏官方最佳实践最好等到您的用户使用您的应用几次后,再展示您的第一个应用打开广告。在您的用户等待您的应用加载的时间展示应用打开广告。如果您在应用打开广告下方有一个加载屏幕,并且您的加载屏幕在广告关闭之前完成加载,您可能需要在adDidDismissFullScreenContent方法中......
  • 左偏树学习笔记
    一、前言左偏树是一种可以在\(O(\logn)\)内快速合并的堆式数据结构。具体来说,插入一个元素:\(O(\logn)\)。查询最值:\(O(1)\)。删除最值:\(O(\logn)\)。合并:\(O(\logn)\)。减少一个元素的值:\(O(\logn)\)。同时它可以持久化。二、定义外节点:左儿子或者右儿子为空的......
  • 计组笔记:
    第一章计算机系统概述取自加以个人理解:https://blog.csdn.net/haojie_duan/article/details/112739522【复习提示】本章是组成原理的概述,考查时易针对有关概念或性能指标出选择题,也可能综合后续章节的内容出有关性能分析的综合题。掌握本章的基本概念,是学好后续章节的基础......