浙江铃声推荐联盟

JavaScript实现对象继承的几种方式

前端学习营2019-04-09 13:08:36

对语言有一定了解的同学应该对于“面向对象”这四个字应该是很熟悉的,对于JAVA,C#这类的编程工程师来说,这是必备的一个概念。但对于前端来说,这个概念似乎不是经常提起。


很多人运用JS还是以特效和框架为主,如果你不是做插件开发或者平台开发,否则基本运用不到JS里面的面向对象编程这一个概念。JavaScript作为一门面向对象编程语言,所以基本的面向对象特征还是存在的,本文就着重讲到如何运用JS实现面向对象中继承这一个概念。在阅读本文之前,首先得对JS中原型和原型链要有一定的了解,因为JS对象都是基于原型和原型链的,自然继承肯定是跟原型和原型链有关系。


所谓继承,就是只一个对象是可以直接使用另外一个对象的属性或者方法的,这个过程中肯定有谁继承谁,也就是子类继承父类的情况。在传统基于类的面向对象语言都会有一个关键字extend,但是JS中是没有这个概念的,那么我们该怎样使用JS实现继承了?


由于没有extend关键字,所以JS实现继承方式并不固定,也是利用本身的一个语法糖去进行的,所以比较灵活。总结起来,JS继承大致有一下几种方式

首先我们先定义一个父类

父类对象是可以直接访问父类的属性或者方法的,那么可以通过把父类对象赋值给子类原型,那么子类也就会拥有了父类原型里面的所有原型和方法。下面代码实现这个过程

缺点

  • 要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中

  • 无法实现多继承

  • 来自原型对象的引用属性是所有实例共享的

  • 创建子类实例时,无法向父类构造函数传参

为父类实例添加新特性,作为子类返回实例

缺点

  • 实例是父类的实例,不是子类的实例

  • 持多继承

获取到父类实例,子类拷贝父类已经存在可枚举的属性或者方法。

缺点

  • 效率较低,内存占用高(因为要拷贝父类的属性

  • 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

通过构造函数模式和原型链继承方式实现继承,结合一起实现实例与原型双向继承。

缺点

  • 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)