博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS的继承方式
阅读量:7054 次
发布时间:2019-06-28

本文共 2952 字,大约阅读时间需要 9 分钟。

JS继承的实现方式

首先,先有一个父类:

// 定义一个动物类function Animal (name) {  // 属性  this.name = name || 'Animal';  // 实例方法  this.sleep = function(){    console.log(this.name + '正在睡觉!');  }}// 原型方法Animal.prototype.eat = function(food) {  console.log(this.name + '正在吃:' + food);};复制代码

原型链继承

核心:将父类的实例作为子类的原型

function Cat(){}Cat.prototype = new Animal();Cat.prototype.name = 'cat';// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.eat('fish'));console.log(cat.sleep());console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true复制代码

优点:

  1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例
  2. 父类新增原型方法/原型属性,子类都能访问到
  3. 简单,易于实现

缺点:

  1. 可以在Cat构造函数中,为Cat实例增加实例属性。如果要新增原型的属性和方法,则必须放在new Animal() 这样的语句之后执行
  2. 无法实现多继承
  3. 来自原型对象的所有属性被所有实例共享
  4. 创建子类实例时,无法向父类构造函数传参。

构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Cat(name){    Animal.call(this);    this.name = name || 'Tom';}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true复制代码

优点:

  1. 解决了原型继承中,子类实例共享父类引用属性问题
  2. 创建子类实例时,可以向父类传递参数
  3. 可以实现多继承(call多个父类对象)

缺点:

  1. 实例并不是父类的实例,只是子类的实例
  2. 只能继承父类的实例属性和方法,不能继承原型属性/方法
  3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能。

实例继承

核心:为父类实例添加新特性,作为子类实例的返回

function Cat (name){    var instance = new Animal();    instance.name = name || 'Tom';    return instance;}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false复制代码

优点:

  1. 不限制调用方式,不管是new子类还是子类(),返回的对象都具有相同的效果

缺点:

  1. 实例是父类的实例,不是子类的实例
  2. 不支持多继承。

拷贝继承

function Cat(name){    var animal = new Animal();    for(var p in animal()){        Cat.prototype[p] = animal[p];    }        Cat.prototype.name = name || 'Tom'}// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true复制代码

优点:

  1. 支持多继承

缺点:

  1. 效率较低,内存占用率高(因为要拷贝父类的属性)
  2. 无法获取父类不可枚举的方法

组合继承

核心:通过调用父类的构造,继承父类的属性并保留传参的有点,然后通过将父类实例作为子类原型,实现函数复用。

function Cat(name){    Animal.call(this);    this.name = name || 'Tom'}Cat.prototype = new Animal();Cat.prototype.constructor = Cat;// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // true复制代码

优点:

  1. 弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
  2. 既是子类的实例,也是父类的实例
  3. 不存在引用属性共享问题
  4. 可传参
  5. 函数可复用

缺点:

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

寄生组合继承

核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造函数的时候,就不会初始化两次实例方法/属性,避免组合继承的缺点

function Cat (name){    Animal.call(this)    this.name = name || 'Tom'}(function(){    //创建一个没有实例方法的类    var Super = function(){};    Super.prototype = Animal.prototype;    //将实例作为子类的原型    Cat.prototype = new Super();})()// Test Codevar cat = new Cat();console.log(cat.name);console.log(cat.sleep());console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); //true复制代码

优点:

1.堪称完美

缺点:

1.实现较为复杂

仅用于个人整理,参考

转载于:https://juejin.im/post/5c98aac46fb9a070f4312e14

你可能感兴趣的文章
去除中国菜刀密码的方法
查看>>
PHP下载断点续传 转
查看>>
【新手】【转】如何学习java程序设计
查看>>
企业邮箱发送不到sina、hotmail等解决
查看>>
如果finalize()抛出异常会怎样?
查看>>
自己的微博
查看>>
php取整函数ceil,floor,round,intval函数的区别
查看>>
NH5-Nhibernate映射中的三种关系
查看>>
SpringBoot项目启动时自动执行指定方法
查看>>
设计模式(行为型模式)——命令模式(Command)
查看>>
vi常用命令
查看>>
Office 2013 兼容性测试(四)——部署遥测处理器
查看>>
Struts1和Struts2的区别和对比
查看>>
Forms开发中触发器的执行顺序
查看>>
SEO博客三个月没更新排行骤步康复
查看>>
JQuery 插件开发的入门介绍
查看>>
马哥2016全新Linux+Python高端运维班第五周作业
查看>>
联想扬天A4680R台式电脑增加内存不识别的解决方案
查看>>
(5)Powershell别名(Alias)
查看>>
我的友情链接
查看>>