Web前端之路

JavaScript 继承

2019-07-09  本文已影响6人  _玖柒_

前言

在面向对象的语言中,讲究封装 继承 多态,而JavaScript这门号称万物皆对象的语言当然也有继承这一说,让我们来看看JS基于原型链的继承,和传统编程语言的区别吧!
PS:有对原型链不太了解的朋友,请移步JavaScript 原型链


原型链继承

这种继承方式是以前最经典最简单的继承方式,每一个函数对象(类)都有prototype,返回对象原型的引用,我们可以给它赋值一个对象,就可以达到原型链继承,废多看码!

  function child() {
    this.age = 12;
  }
  function parent() {
    this.name = "老王";
    this.sex = "男";
    this.age = 42;
  }
  child.prototype = new parent();
  let c = new child();
  console.log(c);
  console.log(c.age, c.name, c.sex);

上面的例子定义了两个类,其中child的原型指向了parent,实现了根据原型链继承,让我们来看看效果


虽然child实例下没有name sex属性,但是由于Js原型链查找的原因,还是能够正常输出c.namec.sex,达到了我们继承的目的

this继承

这种方式是将父对象的this拿到,获取到父对象的属性,看代码:

  function child() {
    Parent.call(this);
    this.age = 12;
    this.name = "小王";
  }
  function Parent() {
    this.name = "老王";
    this.sex = "男";
    this.age = 42;
  }
  let c = new child();
  console.log(c);
  console.log(c.age, c.name, c.sex);

上方的案例中,在child函数内部执行了父函数的call函数,原理就是使用call函数将Parentthis指向了child,所以,看效果吧:


大家要注意,call的执行位置是在第一句,所以相同的属性Parent会被child属性覆盖,但是如果call在下面执行,那call上方与父对象相同的属性,则会被父对象覆盖,这取决于js代码的执行顺序

复制继承

大概就是把2个对象的实例遍历一次,然后把父对象的实例属性丢给子对象,嗯,大概长这样

  function Parent() {
    this.name = "老王";
    this.sex = "男";
    this.age = 42;
  }

  function child() {
    this.extends = Parent => {
      for (const key in Parent) {
        console.log(key);
        this[key] = Parent[key];
      }
    };
    this.age = 12;
    this.name = "小王";
  }
  let c = new child();
  c.extends(new Parent());
  console.log(c);

这种方式超级不推荐!!!!!


ES6继承

这是最推荐大家使用的一种方案,集所有优点于一身,且看代码:

  class Parent {
    constructor() {
      this.name = "老王";
      this.sex = "男";
      this.age = 42;
    }
  }

  class child extends Parent {
    constructor() {
      super();
      this.age = 12;
      this.name = "小王";
    }
  }

  let c = new child();
  console.log(c);

这种写法是最接近与其他语言的,看下效果吧!



总结

最后,希望官方早日推出多态的实现(封装,继承都已经实现了)

上一篇下一篇

猜你喜欢

热点阅读