extend笔记

科技资讯 投稿 6200 0 评论

extend笔记

JavaScript面向对象

继承extend

1. 概念(主要用途


2. 继承的优点与缺点

2.1 优点

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

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


2.2 缺点

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


3. JS继承的方式

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

3.1 构造函数继承

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 原型链继承

  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

  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

  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]

注意

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

编程笔记 » extend笔记

赞同 (31) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽