【魔仙带你打通new原理/继承相关知识点🏁】

103 阅读1分钟

new原理

new的关键:执行一个构造函数 返回一个实例对象

内部执行步骤:
graph TD
创建一个新对象 --> 对象指向构造函数的原型-绑定this-this指向新对象 --> 执行构造函数 --> 返回新对象
手写 New
function create(fn,...args){
  if(typeof fn !== 'function'){
     throw 'fn not a function'
  }
  var obj = Object.create(fn.prototype)
  var res = fn.apply(obj,args)
  return res instanceof Object ? res : obj
}
1.obj继承了函数fn的原型 拥有了它身上的属性
2.改变函数的this指向 将this指向obj这个对象 这样obj就可以访问到fn构造函数上的属性
3.如果有返回值 则将其作为new操作返回的对象 否则返回obj

继承

  1. 不使用Object.create 组合继承(构造函数继承、原型链继承)
  2. 使用Object.create 寄生组合继承(原型式继承、寄生式继承)
1.构造函数继承
借助call
function Parent(){
  this.name = 'parent'
}
function Child(){
  Parent.call(this)
  this.type = 'child'
}
但是这种方式无法继承父类的方法
2.原型链继承
function Parent(){
  this.name = 'parent'
  this.play = [1,2]
}
function Child(){
  this.type = 'child'
}
Child.prototype = new Parent()
这种方式可以访问父类的属性和方法 但是当创建两个子类的实例时 改变其中一个 另一个也会被改变 因为他们共用的一个原型

3.上面两种组合继承
function Parent(){
  this.name = 'parent'
  this.play = [1,2]
}
function Child(){
  Parent.call(this)
  this.type = 'child'
}
Child.prototype = new Parent()

3.寄生组合继承:解决了组合继承中 子类继承父类的无用属性的问题
function Parent(){
  this.name = 'parent'
  this.play = [1,2]
}
function Child(){
  Parent.call(this)
  this.type = 'child'
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child

ES6 Class继承 js中不存在类的概念 class只是语法糖🍬 其本质是函数
class Parent {
  constuctor(value){
    this.val = value
  }
  getValue(){
    console.log(this.val)
  }
}
class Child extends Parent{
  constuctor(value){
    super(value)
    this.val = value
  }
}
let child = new child(520)
child.getValue() //输出520