js 常用继承方法

136 阅读3分钟
 function Person(name, age) {
  // this => s1
  this.name = name
  this.age = age
  this.say = function () {
  console.log('Hello World')
    }
  }
1 构造函数继承/Call 式继承
  function Star(name, age) {
  // this => s1
  Person.call(this, name, age)
  }
  const s1 = new Star('尼古拉斯.赵四', 18)
  console.log(s1.name)
  console.log(s1.age)
  s1.say() 



  function Person(name, age) {
  // this => s1
  // this => s2
  this.name = name
  this.age = age
  this.say = function () {
  console.log('Hello World')
    }
  }

  function Star(name, age) {
  // this => s1
  // this => s2
  Person.call(this, name, age)
  }
  const s1 = new Star('尼古拉斯.赵四', 18)
  const s2 = new Star('尼古拉斯.赵六', 19)

  // !#2 构造函数继承的问题,明明干的事是一样,方法却不等,浪费内存空间

  console.log(s1.say === s2.say) // false */


  function Person(name, age) {
  this.name = name
  this.age = age
  }

  // !#3 构造函数继承的问题,期望挂到父类的原型上,但是构造函数继承搞不定

  Person.prototype.say = function () {
  console.log('Hello World')
  }

  function Star(name, age) {
  Person.call(this, name, age)
  }
  const s1 = new Star('尼古拉斯.赵四', 18)
  s1.say() 



  function Person(name, age) {
  this.name = name
  this.age = age
  }



  Person.prototype.say = function () {
  console.log('Hello World')
  }


  function Star(name, age) {
  Person.call(this, name, age)
  }
  Star.prototype = Person.prototype

  // !#4 相互影响,明明给儿子挂的方法

  Star.prototype.play = function () {
  console.log('play')
  }

  // 却影响到父亲了
  const p1 = new Person()
  p1.play() 

2 原型继承


  function Person(name, age) {
  this.name = name
  this.age = age
  }



  Person.prototype.say = function () {
  console.log('Hello World')
  }



  function Star(name, age) {
  Person.call(this, name, age)
  }

  // p 是 Person 的实例,我说 Person 有的 p 都有,所以 p 有 name、age、say
  const p = new Person()
  // !#5 这儿确实会影响 p 实例,但是没关系,p 实例仅仅是用来继承的,没人用,只要不影响后续通过 new Person 创建的新实例就 ok
  Star.prototype = p
  Star.prototype.play = function () {
  console.log('play')
  }



  const s1 = new Star('尼古拉斯1', 18)
  const s2 = new Star('尼古拉斯2', 18)
  console.log(s1.say === s2.say)

  const ppp = new Person()
  ppp.play() 


  function Person(name, age) {
  this.name = name
  this.age = age
  }



  Person.prototype.say = function () {
  console.log('Hello World')
  }



  function Star(name, age) {
    Person.call(this, name, age)
  }

  const p = new Person()
  Star.prototype = p

  const s1 = new Star('尼古拉斯1', 18)
  // !#6 问题

  console.log(Star.prototype.construcor === Star) // false
  console.log(s1.__proto__.construcor === Star) // false
  console.log(s1.construcor === Star) // false */

3组合继承(构造函数+原型继承)


 function Person(name, age) {
  this.name = name
  this.age = age
  }



  Person.prototype.say = function () {
  console.log('Hello World')
  }



  function Star(name, age) {
  Person.call(this, name, age)
  }

 

  Star.prototype = new Person()
  Star.prototype.construcor = Star


  const s1 = new Star('尼古拉斯1', 18)

  // !#6 问题

  console.log(Star.prototype.construcor === Star)
  console.log(s1.__proto__.construcor === Star)
  console.log(s1.construcor === Star) // false

 构造函数继承(继承的是属性)+原型继承(继承的父类原型上的方法) = 组合继承 */

   function Person(name, age) {
    this.name = name
    this.age = age
  }



  Person.prototype.say = function () 
    console.log('Hello World')
  }



  function Star(name, age) {
    Person.call(this, name, age)
  }

  // !#7 把属性 undefined 给了 Start.prototype,没必要
  Star.prototype = new Person()
  Star.prototype.construcor = Star
  const s1 = new Star('尼古拉斯1', 18) */

4 寄生继承


 function Person(name, age) {
    this.name = name
    this.age = age
  }



  Person.prototype.say = function () {
    console.log('Hello World')
  }



  function Star(name, age) {
    Person.call(this, name, age)
  }



  // 寄生继承,把 Person.prototype 上面的方法寄生给了 Temp.prototype
  function Temp() { }
  // 把 Person.prototype 上面的有的都给了 Temp.prototype
  Temp.prototype = Person.prototype
  const t = new Temp()


  // t 只有 say
  Star.prototype = t
  Star.prototype.construcor = Star
  const s1 = new Star('尼古拉斯1', 18)
  console.log(s1) 



 function Person(name, age) {
    this.name = name
    this.age = age
  }



  Person.prototype.say = function () {
    console.log('Hello World')
  }



  function Star(name, age) {
    Person.call(this, name, age)
  }


  // 寄生继承
  function create(Person) {
    function Temp() { }
    Temp.prototype = Person.prototype
    return new Temp()
  }



  // t 只有 say
  Star.prototype = create(Person)
  Star.prototype.construcor = Star
  const s1 = new Star('尼古拉斯1', 18)
  console.log(s1)

  function Person(name, age) {
    this.name = name
    this.age = age
  }

  Person.prototype.say = function () {
    console.log('Hello World')
  }



  function Star(name, age) {
    Person.call(this, name, age)
  }





  // 寄生继承的封装

  function create(Person, Star) {
    function Temp() {
      // 实例 => t => Star.prototype
      this.construcor = Star
    }
    Temp.prototype = Person.prototype
    return new Temp()
  }



  // t 只有 say
  Star.prototype = create(Person, Star) // create 拿到的结果是 Temp 的实例
  // Star.prototype.construcor = Star

  const s1 = new Star('尼古拉斯1', 18)
  console.log(s1)

  1. 构造函数继承 => 继承的是属性
  2. 原型继承 => 继承的是父类构造函数上的方法
  3. 组合继承 = 构造函数继承 + 原型继承
  4. 原型继承的问题:子类的.prototype 上有无用属性是 undefined
  5. 寄生继承,弄一个新方法,把父类.prototype 等于新方法.prototype,然后把新方法的实例给了子类.prototype
  6. 寄生组合继承 => 构造函数继承 + 寄生继承