JS继承的实现方式:

既然要实现继承,那么首先我们得有一个父类,代码如下:

function Animal(name) {// 属性this.name = name || '小白';// 实例方法this.sleep = function () {console.log(this.name + '正在睡懒觉!');}//实例引用属性this.features = ['11', '22'];}// 原型方法Animal.prototype.eat = function (food) {console.log(this.name + '正在吃:' + food);};

1、原型链继承

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

function Cat(name) {}//把Cat的原型指向AnimalCat.prototype = new Animal();var tom = new Cat('Tom');var kissy = new Cat('Kissy');console.log(tom.name); // "小白"console.log(kissy.name); // "小白"console.log(tom.features); // ["11", "22"]console.log(kissy.features); // ["11", "22"]
tom.name = '小黑';tom.features.push('33');//针对父类实例值类型成员的更改,不影响console.log(tom.name); // "小黑"console.log(kissy.name); // "小白"//针对父类实例引用类型成员的更改,会通过影响其他子类实例console.log(tom.features); // ["11", "22", "33"]console.log(kissy.features); // ["11", "22", "33"]

特点:
1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例
2.父类新增原型方法/原型属性,子类都能访问到
3.简单,易于实现
缺点:
1.可以在Cat构造函数中,为Cat实例增加实例属性。如果要新增原型属性和方法,则必须放在new Animal()这样的语句之后执行。
2.来自原型对象的所有属性被所有实例共享(来自原型对象的引用属性是所有实例共享的)(详细请看附录代码: 示例1)
3.创建子类实例时,无法向父类构造函数传参

2、构造继承

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

function Cat(name) {Animal.call(this);this.name = name || '小黑';}var cat = new Cat();var animl = new Animal();console.log(cat.name);//小黑cat.sleep();//小黑正在睡懒觉console.log(animl.name);//小白animl.name = '大黄';console.log(animl.name);//大黄cat.sleep();//小黑正在睡懒觉!console.log(cat.name);//小黑console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true

特点:
1. 解决了1中,子类实例共享父类引用属性的问题
2. 创建子类实例时,可以向父类传递参数
3. 可以实现多继承(call多个父类对象)
缺点:
1. 实例并不是父类的实例,只是子类的实例
2. 只能继承父类的实例属性和方法,不能继承原型属性/方法
3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

3、实例继承

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

function Cat(name) {var instance = new Animal();instance.name = name || '小黑';return instance;}var cat = new Cat();console.log(cat.name);//小黑cat.sleep();//小黑正在睡懒觉!cat.features.push('33')console.log(cat.features);//["11", "22", "33"]console.log(cat instanceof Animal); // trueconsole.log(cat instanceof Cat); // false

特点:
1.不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
1.实例是父类的实例,不是子类的实例
2.不支持多继承

4、拷贝继承

核心:通过for循环去拷贝父类的每一个对象

//通过循环去copy父类的每一项function Cat(name) {var animal = new Animal();for (var p in animal) {Cat.prototype[p] = animal[p];}Cat.prototype.name = name || '小黑';}var cat = new Cat();console.log(cat.name);//小黑cat.sleep();//小黑正在睡懒觉!console.log(cat instanceof Animal); // falseconsole.log(cat instanceof Cat); // true

特点:
1.支持多继承
缺点:
1.效率较低,内存占用高(因为要拷贝父类的属性)
2.无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

5、组合继承

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

function Person(name, age, sex) {this.name = name;this.age = age;this.sex = sex;}Person.prototype.sayHi = function () {console.log("我是Person的方法");};function Student(name, age, sex, score) {//借用构造函数:属性值重复的问题Person.call(this, name, age, sex);this.score = score;}//改变原型指向----继承Student.prototype = new Person(); //不传值//把原型的指向改回原来Student.prototype.constructor = Student;Student.prototype.eat = function () {console.log("我是Student的方法");};var stu = new Student("小黑", 20, "男", "100分");console.log(stu.name, stu.age, stu.sex, stu.score);//小黑 20 男 100分stu.sayHi();//我是Person的方法stu.eat();//我是Student的方法

特点:
1.可以继承实例属性/方法,也可以继承原型属性/方法
2.既是子类的实例,也是父类的实例
3.不存在引用属性共享问题
4.可传参
5.函数可复用
缺点:
1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

转载于:https://www.cnblogs.com/wanguofeng/p/10718804.html

js 继承的几种方式相关推荐

  1. 学习js继承的6种方式

    关于原型,原型链,构造函数和实例关系,可以参考上一篇文章 地址:juejin.im/post/5cbfb3- js 实现继承的方式一:原型链继承 function Father(){this.name ...

  2. JS 总结之原型继承的几种方式

    在之前的总结中,我们详细分析了原型<JS 总结之原型>,原型很大作用用于模拟继承,这一次,我们来聊原型继承的几种方式. function Person (age) {this.age = ...

  3. 继承有几种方式,分别是什么,想要实现继承可以使用哪些方法

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [继承有几种方式 ...

  4. 可以实现继承的几种方式

    继承的几种方式 说起继承,又是一个老生常谈的问题了.今天来讲讲继承的几种方法以及他们的优缺点吧. 源码地址:点击这里 一.原型链继承 原型链继承:通过原型将一个引用类型继承另一个引用类型的属性和方法. ...

  5. Django中Model继承的三种方式

    Django中Model继承的三种方式 Django中Model的继承有三种: 1.抽象继承 2.多表继承 3.proxy model(代理model) 1.抽象继承 第一种抽象继承,创建一个通用父类 ...

  6. JavaScript系列-02 HTML嵌入js代码的第二种方式

    javaScript系列 HTML中嵌入js代码的第二种方式 脚本块的方式 文章目录 javaScript系列 前言 一.了解脚本块的方式 1.1运行规则 二.执行原理 1.编写代码 2.效果 总结 ...

  7. 在HTML 中嵌入 JS 代码的三种方式

    一,在HTML中嵌入JS代码的第一种方式:行间事件 行间事件是指将JavaScript函数写到HTML元素中的执行事件. 1.JavaScript 是一种事件驱动型的编程语言,通常都是在发生某个事件的 ...

  8. JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量

    文章目录 JavaScript 01 关于JavaScript 1.1 JS的发展历史 1.2 JS的特性 1.3 JS的组成 1.4 JSP和JS的区别 02 在HTML中嵌入JS代码的三种方式 2 ...

  9. HTML嵌入JS代码的三种方式

    目录 一.HTML嵌入JS代码的第一种方式:直接加一个事件句柄跟表达式 二.HTML嵌入JS代码的第二种方式:脚本块 三.HTML嵌入JS代码的第三种方式:外部引入js文件 一.HTML嵌入JS代码的 ...

最新文章

  1. 从两个bug来看Javascript的装载
  2. AI领域的人才短缺,原因是什么?该如何解决?
  3. 免费的FTP linux 服务器中文,linux ftp服务器的搭建和中文字体乱码的解决
  4. C#Socket开发TCP详解(二)
  5. Linux之Centos允许root连接ftp
  6. 读书笔记之:高质量程序设计指南——C++/C
  7. 双击java安装包没反应_wps安装包双击没反应
  8. Hadoop学习整理
  9. python3GUI--抖音无水印视频下载工具(附源码)
  10. 【R语言 南丁格尔玫瑰图绘制】
  11. 软件项目管理与素质拓展-2.2什么是项目
  12. 吊炸天SpringBoot接入支付宝支付【附关键代码】
  13. 苏州大学转专业计算机2019汇总,关于2019-2020学年第一学期普通本科生转专业名单的公示...
  14. android mkdir失败_在/ sdcard中创建目录失败
  15. uniapp使用艺术字
  16. OpenCV-Python 中文教程15——OpenCV 中的轮廓
  17. 梦想起航商务工作PPT模板-优页文档
  18. 多种导出方式,教你快速将每个快递信息导出CSV表格
  19. html打开方式解锁,解锁bootloader
  20. 迷宫问题寻宝(c++实现,求最短路径,显示路径)

热门文章

  1. zcmu- 聪明的美食家 最长不连续上升子序列(nlogn)
  2. android WebView详解,常见漏洞详解和安全源码(下)
  3. Android短信发送流程之普通短信发送(原)
  4. JZOJ 5907. 【NOIP2018模拟10.16】轻功(qinggong)
  5. html div 纵向居中,内容居中分为div内容水平居中与div内容垂直居中
  6. 大工计算机应用基础在线测试2,大工15秋《计算机应用基础》在线测试2
  7. c malloc 头文件_C语言提高篇_malloc,realloc和calloc的区别
  8. python底层源码_Python每天一分钟:解析python底层类的实现原理——竟然是type()
  9. 查全率[召回率]与精度[查准率] 之辨析
  10. 系统重装后 Endnote 不能和Word联用的解决方法