js 继承

js 继承(子类拥有父类的属性和方法)

constructor:
function Parent (name){
this.name = name
this.arr = [1]
}
let Child = new Parent(‘张三’)
Parent.constructor = Function //constructor指向构造函数
Child.constructor = Parent
Child.prototype.constructor = Child
结论:函数的constructor在原型属性prototype上,执向函数本身。instance of 判断变量的构造函数时通过原型链去查找。

原型链继承

function Child1 (like) {
  this.like = like
}
Child1.prototype = new Parent('张三')
Child1.prototype.constructor = Child1
console.log(Child1)
console.log(Child1.name)
console.log(Child1.prototype.name)
console.log(Child1.prototype.arr)
let body = new Child1()
console.log(body.name, body.arr)
// 结论:将父类的属性和方法放到子类的原型属性prototype上
// 缺点:不能向父类传参,并且拥有了一些子类不需要的属性和方法

构造函数继承

/* function Parent (name) {
  this.name = name
  this.sex = '男'
  this.say = function () {
    console.log('hello')
  }
}
Parent.prototype.arr = [1, 2]
function Child (name, like) {
  this.like = like
  this.age = 18
  Parent.myCall(this, name)
}
let body1 = new Child('张三', '打篮球')
let body2 = new Child('李四', '游泳')
console.log(body1)
console.log(body2) */
// 结论:通过call方法特性执行一次父类构造函数并将参数传进去,然后改变this指向,使子类拥有父类的属性和方法
// 优点:可以传参
// 缺点:1,没有共享父类的方法,2,不能继承原型链的属性

组合继承

/*  function Parent (name) {
   this.name = name
   this.sex = '男'
   this.say = function () {
     console.log('hello')
   }
 }
 Parent.prototype.arr = [1, 2]
 function Child (name, like) {
   this.like = like
   this.age = 18
   Parent.myCall(this, name)
 }
 Child.prototype = new Parent()
 Child.prototype.constructor = Child
 let body1 = new Child('张三', '打篮球')
 let body2 = new Child('李四', '游泳') */
//结论:原型链继承和构造函数继承的组合版
//缺点:执行了两次构造函数,会多缓存一个内存

寄生组合继承

/*     function Parent (name) {
      this.name = name
      this.sex = '男'
      this.say = function () {
        console.log('hello')
      }
    }
    Parent.prototype.arr = [1, 2]
    function Child (name, like) {
      this.like = like
      this.age = 18
      Parent.myCall(this, name)
    }
    Child.prototype = Object.create(Parent.prototype) //创建一个新对象,并且将传入的对象设为新对象的__proto__
    Child.prototype.constructor = Child
    let body1 = new Child('张三', '打篮球')
    let body2 = new Child('李四', '游泳')

    console.log(body1);
    console.log(body2); */
//结论:继承的完美解决方案

Es6的继承

class Person {
  constructor(name, age) {  //new 改类的时候会执行constructor(构造器)
    this.name = name
    this.age = age
    this.sex = '男'
    return null
  }
  say () {                 // 这种直接定义在类上的方法是挂在该类的prototype上的
    console.log(1)
  }
  static like = 'sport'
  static sayHello () {     // 直接通过该类.方法就可以获取
    console.log('hello')
  }
}
class Student extends Person {
  constructor() {
    // console.log(this);
    // console.log(super);
    super('zs')

  }
}
console.log(Student)
let s1 = new Student()
console.log(s1.say);
console.log(s1.sayHello);
结论:继承的时候会执行构造器,并且改变this指向为子类。挂在static上的属性和方法不被继承
           ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。不执行的话子类没有自己的this
           子类super执行 :父类.prototype.constructor.call(this, props)`
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值