前言

本系列主要整理前端面试中需要掌握的知识点。本节介绍JS如何实现继承。

文章目录

  • 前言
  • 一、什么是继承
  • 二、实现方式
    • 1. 原型链继承
    • 2. 构造函数继承
    • 3. 组合继承
    • 4. 原型式继承
    • 5. 寄生式继承
    • 6. 寄生组合式继承(最优继承方法)
  • 三、总结

一、什么是继承

如果一个类别B继承自另一个类别A,就把这个B成为A的子类,而把A成为B的父类,或者A是B的超类

继承的优点:

  • 继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码
  • 在子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性的方法,使其获得于父类不同的功能。

二、实现方式

JS中常用的继承实现方式为:原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。

1. 原型链继承

原型链继承中涉及到构造函数、原型和实例,三者之间存在着一定的关系,即每一个构造函数都有一个原型对象,原型对象又包含一个指向构造函数的指针,而实例则包含一个原型对象的指针

function Parent(){this.name = 'parent1';this.play = [1,2,3]
}
function Child(){this.type = 'child2';
}
Child.prototype = new Parent();  //Child是Parent的子类,Child继承Parent
console.log(new Child());      //包含Parent和Child中的所有属性


但是,无论Child有多少个实例,他们的指针都是指向同一个地方的:

function Parent(){this.name = 'parent1';this.play = [1,2,3]
}
function Child(){this.type = 'child2';
}
Child.prototype = new Parent();  //Child是Parent的子类,Child继承Parent
console.log(new Child());      //包含Parent和Child中的所有属性var s1 = new Child();   //实例s1
var s2 = new Child();   //实例s2
s1.play.push(4);     //向s1的play中加入4,但其实是向原型对象中加入值,他们使用的同一个原型对象
console.log(s1.play,s2.play);  //都是[1,2,3,4]

2. 构造函数继承

function Parent(){this.name = 'parent1';
}Parent.prototype.getName = function(){return this.name;
}function Child(){Parent.call(this);this.type = 'child'
}let child = new Child();
console.log(child);   //正常输出
console.log(child.getName()); // 报错
  • 父类原型对象中一旦存在父类之前自己定义的方法,那么子类将无法继承这些方法;
  • 相比第一种原型链继承方式,父类的引用属性不会被共享,优化了第一种继承方式的弊端,只能继承父类的实例属性和方法,不能继承原型属性或者方法。

3. 组合继承

function Parent(){this.name = 'parent';this.play = [1,2,3];
}Parent.prototype.getName = function(){return this.name;
}function Child(){Parent.call(this);this.type = 'child';
}
Child.prototype = new Parent();
var s1 = new Child();
var s2 = new Child();
s1.play.push(4);
console.log(s1.play,s2.play);    //互不影响
console.log(s1.getName());     //正常输出
console.log(s2.getName());     //正常输出

这种写法父类的引用属性不会被共享,且能获得原型的属性或方法,缺点是Parent执行了两次,造成了多构造一次的性能开销。

4. 原型式继承

let parent = {name:"parent",friends:['p1','p2','p3'],getName:function(){return this.name}
};parent.getName = function(){return this.name;
}let person1 = Object.create(parent);
person1.name = "tom";
person1.friends.push("jerry");let person2 = Object.create(parent);
person1.friends.push('lucy');console.log(person1.name);  //tom
console.log(person2.name);   //parent
console.log(person1.friends); //['p1', 'p2', 'p3', 'jerry', 'lucy']
console.log(person2.friends); //['p1', 'p2', 'p3', 'jerry', 'lucy']

由于Object.create实现的是浅拷贝,多个实例的引用类型属性指向相同的内存,存在篡改的可能。

5. 寄生式继承

let parent = {name:'parent',friends:['p1','p2','p3'],getName:function(){return this.name;}
};function clone(original){let clone = Object.create(original);clone.getFriends = function(){return this.friends;}return clone;
}let person = clone(parent)
console.log(person.getName());
console.log(person.getFriends());

优缺点与原型式继承一样。

6. 寄生组合式继承(最优继承方法)

function clone(parent,child){child.prototype = Object.create(parent.prototype);child.prototype.constructor = child;
}function Parent(){this.name = 'parent';this.play = [1,2,3];
}
Parent.prototype.getName = function(){return this.name;
}
function Child(){Parent.call(this);this.friends = 'child';
}clone(Parent,Child);
Child.prototype.getFriends = function(){return this.friends
}
let person = new Child();
console.log(person);
console.log(person.getName());
console.log(person.getFriends());

extends可以直接实现继承

class Person {constructor(name){this.name = name}getName = function(){console.log('Person:',this.name);}
}
class Gamer extends Person {constructor(name,age){super(name)this.age = age}
}
const asuna = new Gamer('Asuna',20)
asuna.getName()

三、总结

【前端知识之JS】JS如何实现继承相关推荐

  1. 「JavaScript灵魂之问」前端知识梳理之 JS 篇(中篇)

    对象基础 对象前置知识 /* 对象基础知识 */var teacher = {name: '张三',age: 32,sex: 'male',height: 176,weight: 130,teach: ...

  2. 前端知识总结汇总!(HTML、CSS、JS、jQuery、vue、微信小程序)

    前端知识总结汇总!(HTML.CSS.JS.jQuery.vue.微信小程序) 前端理论考核题 1 / HTML 1.DOCTYPE 的作用是什么?标准模式与兼容模式各有什么区别? !DOCTYPE是 ...

  3. 前端学习笔记(js基础知识)

    前端学习笔记(js基础知识) JavaScript 输出 JavaScript 数据类型 常见的HTML事件 DOM 冒泡与捕获 流程控制语句 for..in 计时器 let,var,const的区别 ...

  4. 【repost】一探前端开发中的JS调试技巧

    有请提示:文中涉及较多Gif演示动画,移动端请尽量在Wifi环境中阅读 前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问 ...

  5. 后端视角下的前端框架之Vue.js初探

    背景 作为常年搞后端的自己来说,除了多年前学习的一点关于HTML的皮毛,对现在的前端技术栈可谓是一窍不通.但是因为最近在做的内部业务全链路监控系统,负责前端的同事做到一半去搞别的项目了,为了把项目落地 ...

  6. 前端构建工具 Gulp.js 上手实例

    在软件开发中使用自动化构建工具的好处是显而易见的.通过工具自动化运行大量单调乏味.重复性的任务,比如图像压缩.文件合并.代码压缩.单元测试等等,可以为开发者节约大量的时间,使我们能够专注于真正重要的. ...

  7. 前端清单之Vue.js篇

    2019独角兽企业重金招聘Python工程师标准>>> 教程实践 基于 Vue 与 DeepStream 构建实时 CRUD 应用:Vue 是专注于 JavaScript UI 的渐 ...

  8. 前端复习8:JS高级

    前端复习8:JS高级 1.对象 1.1 面向过程与面向对象 1.2 对象与类 2 构造函数和原型 2.1 构造函数 2.2 构造原型prototype 2.2 对象原型 2.3 constructor ...

  9. 学习 前端开发中的JS调试技巧(断点)

    http://seejs.me/2016/03/27/jsdebugger/ alert() console.log(xxxx) JS断点调试 JS断点调试,即是在浏览器开发者工具中为JS代码添加断点 ...

最新文章

  1. java高并发(四)并发编程与线程安全
  2. 【Linux】一步一步学Linux——ssh-copy-id命令(180)
  3. Android为TV端助力 转载:android自定义view实战(温度控制表)!
  4. Oracle数据库不同损坏级别的恢复详解
  5. aws iam php,php-AWS4签名密钥-本教程错误吗?
  6. node定时任务php 卡,在NodeJs中如何实现定时任务(详细教程)
  7. 通过CMD命令行获取文件夹下的所有文件名称(电脑小白专用)
  8. (一) js + Vue 写扫雷
  9. vue string转date_进阶高级前端,这9种Vue技术你掌握了吗?
  10. 添加halcon图像显示控件_Halcon的C#二次开发及经验分享
  11. JAVA日常游玩-----用EnumMap优化代码。
  12. 充电桩市场与发展前景分析
  13. 还没对Docker加以限制?埋下的安全隐患了解一下
  14. 微信小程序项目-最常用网盘助手
  15. Vmware 虚拟机安装 Ubuntu
  16. JdbcTemplate的增删改查用法
  17. 移动端车牌识别:新能源车牌识别上线
  18. 基于知识图谱的推荐系统(KGRS)综述
  19. FFCreator制作视频(合成视频)
  20. 关于文件读写缓存的问题(flush的使用场景)

热门文章

  1. 华为命令手册_网络故障排查之tracert命令详解
  2. mysql查询第八页_第八节:MySQL之Select指令详解和相关练习
  3. 使用51单片机自制电子万年历(包含驱动、基本万年历、闹钟、日程、修改时间等)
  4. Soft:QtDesigner软件界面的简介、案例应用之详细攻略
  5. 苹果4G版iPad Air 2和iPad mini 3 发布
  6. 2023管理员申请书怎么写最新范文
  7. 计算机开机看不到用户,电脑开机进不了系统常见故障及解决方法
  8. 【考研词汇训练营】Day18 —— amount,max,consider,account,actual,eliminate,letter,significant,embarrass,collapse
  9. 第一款自己的RPG游戏--生成心中的世界(二)
  10. ZOJ刷题(初学者题目)