JS中的继承

458 阅读2分钟

每次谈到OOP编程 大家又要开始diss Javascript。不是面向对象语言 是一门弱类型语言 云云。。。尽管这样 到了2020你还是要被问JS继承是如何实现的

原型链继承

这里简单说一下原型链是个啥。每个构造函数都有一个原型对象,原型对象内都包含执行构造函数的指针;每个实例中都包含指向构造函数的原型对象的内部指针。这种层层指向的关系被称为原型链。

instance._prpto_ = construcor.prototype = object;

原型链继承顾名思义是借助原型链实现的

function  father(){
    this.type = true
}

father.prototype.getType = function (){
    return this.type;
}

function child(){
    this.type = false;
}
// 将子类的原型对象指向父类的实例
child.prototype = new father();
let instance1 = new father();
let instance2 = new child();
console.log(instance1.type,instance2.type) // true,false

console.log(instance2.getType()) false

这种方式实现了子类对父类构造函数以及原型对象上的方法及属性继承,但是没有办法向构造函数传参

构造函数继承

构造函数继承实现了可以向构造函数传参,但是没办法自定义成员方法和属性

function father(name) {
  this.name = name;
}

father.prototype.getName = function() {
  return this.name;
};

function child() {
  father.call(this, "lily");
}

let instance1 = new father("tina");
let instance2 = new child();

console.log(instance1.name,instance1.getName()); // output: tina tina
console.log(instance2.name,instance2.getName()); // output:lily,lily

组合继承

组合继承结合了原型链继承和构造函数继承两种方式;缺点是每次都会有两次构造函数的调用;

function father(name) {
  this.name = name;
}

father.prototype.getName = function() {
  return this.name;
};

function child() {
  father.call(this, "lily");
  this.age = 18;
}

child.prototype = new father();
child.prototype.constrctor = child;
let instance1 = new father("tina");
let instance2 = new child();

console.log(instance1.getName());
console.log(instance2.getName());

原型式继承

ECMAScript5新增了Object.create()方法,将传入的第一个参数作为原型对象,第二个参数与Object.definePorperty类似,传入可枚举的对象作为成员属性,内部实现如下

Function object(o){
    function F(){}
    F.prototype = 0;
    return new F();
}

继承实现 不需要构造函数

let person = { name: "lily" };

let son = Object.create(person, { age: { value: 18 } });
console.log(son.age,son.name); // output: 18,'lily'

寄生式继承

寄生式继承参考工厂模式,创建一个封装了继承过程的函数 最后一个新的对象

function createAnother(original) {
  let clone = Object(original);
  clone.sing = function() {
    console.log("sing");
  };
  return clone;
}
let person = { name: "lily", friends: ["jack", "van", "tony"] };

let son = createAnother(person);

console.log(son.name); // output: 'lily'

寄生组合式继承

这种方式结合了寄生继承和组合继承方式

function inheri(father, son) {
  let prototype = Object(father.prototype);
  prototype.constrctor = son;
  son.prototype = prototype;
}
function father(name) {
  this.name = name;
}

function son() {
  father.call(this, "son");
}

inheri(father, son);

let instance1 = new son();
console.log(instance1.name);


es6中的继承

提供语法糖 定义了关键字 extends super


class father {
  constructor() {
    this.name = "lily";
  }
}

class child extends father {
  constructor() {
    super();
    this.age = 18;
  }
  getAge() {
    return this.age;
  }
}

let instance1 = new father();
let instance2 = new child();

console.log(instance1.name, instance2.getAge()); // output 'lily', 18

补充typeScript中的继承

class Tparent{
  name:string;//类的属性
  //类的构造函数
  constructor(name:string){
      this.name=name;
  }
  run():string{
      return `${this.name}singsong`
  }
}

class Web extends Tparent{
  constructor(name:string){
      super(name);
  }
}

var w=new Web("lily");
console.log (w.run());