自我介绍:大家好,我是吉帅振的网络日志;微信公众号:吉帅振的网络日志;前端开发工程师,工作4年,去过上海、北京,经历创业公司,进过大厂,现在郑州敲代码。

JS继承专栏

1【JS继承】什么是JS继承?

2【JS继承】常见的7种继承方式

3【JS继承】JS继承之原型链继承

4【JS继承】JS继承之构造函数继承

5【JS继承】JS继承之组合继承

6【JS继承】JS继承之原型式继承

7【JS继承】JS继承之寄生式继承

8【JS继承】JS继承之寄生组合式继承

9【JS继承】JS继承之ES6 Class继承

一、原型链继承

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

SubType.prototype = new SuperType()// 所有涉及到原型链继承的继承方式都要修改子类构造函数的指向,否则子类实例的构造函数会指向SuperType。SubType.prototype.constructor = SubType;

优点:父类方法可以复用。

缺点:

  • 父类的引用属性会被所有子类实例共享

  • 子类构建实例时不能向父类传递参数

二、构造函数继承

核心:将父类构造函数的内容复制给了子类的构造函数。这是所有继承中唯一一个不涉及到prototype的继承。

SuperType.call(SubType);

优点:和原型链继承完全反过来

  • 父类的引用属性不会被共享

  • 子类构建实例时可以向父类传递参数

缺点:父类的方法不能复用,子类实例的方法每次都是单独创建的。

三、组合继承

核心:原型式继承和构造函数继承的组合,兼具了二者的优点。

function SuperType() {this.name = 'parent';this.arr = [1, 2, 3];}SuperType.prototype.say = function() {console.log('this is parent')}function SubType() {SuperType.call(this) // 第二次调用SuperType}SubType.prototype = new SuperType() // 第一次调用SuperType

优点:

  • 父类的方法可以被复用

  • 父类的引用属性不会被共享

  • 子类构建实例时可以向父类传递参数

缺点:调用了两次父类的构造函数,第一次给子类的原型添加了父类的name, arr属性,第二次又给子类的构造函数添加了父类的name, arr属性,从而覆盖了子类原型中的同名参数。这种被覆盖的情况造成了性能上的浪费。

四、原型式继承

核心:原型式继承的object方法本质上是对参数对象的一个浅复制。

优点:父类方法可以复用。

缺点:

  • 父类的引用属性会被所有子类实例共享

  • 子类构建实例时不能向父类传递参数

function object(o){function F(){}F.prototype = o;return new F();}var person = {name: "Nicholas",friends: ["Shelby", "Court", "Van"]};var anotherPerson = object(person);anotherPerson.name = "Greg";anotherPerson.friends.push("Rob");var yetAnotherPerson = object(person);yetAnotherPerson.name = "Linda";yetAnotherPerson.friends.push("Barbie");alert(person.friends);   //"Shelby,Court,Van,Rob,Barbie"

ECMAScript 5 通过新增 Object.create()方法规范化了原型式继承。这个方法接收两个参数:一 个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。在传入一个参数的情况下, Object.create()与 object()方法的行为相同。——《JAVASCript高级编程》

所以上文中代码可以转变为:

var yetAnotherPerson = object(person); => var yetAnotherPerson = Object.create(person);

五、寄生式继承

核心:使用原型式继承获得一个目标对象的浅复制,然后增强这个浅复制的能力。

优缺点:仅提供一种思路,没什么优点。

function createAnother(original){var clone=object(original);    //通过调用函数创建一个新对象clone.sayHi = function(){      //以某种方式来增强这个对象alert("hi");};return clone;                  //返回这个对象}var person = {name: "Nicholas",friends: ["Shelby", "Court", "Van"]};var anotherPerson = createAnother(person);anotherPerson.sayHi(); //"hi"

六、寄生组合继承

刚才说到组合继承有一个会两次调用父类的构造函数造成浪费的缺点,寄生组合继承就可以解决这个问题。

function inheritPrototype(subType, superType){var prototype = object(superType.prototype); // 创建了父类原型的浅复制prototype.constructor = subType;             // 修正原型的构造函数subType.prototype = prototype;               // 将子类的原型替换为这个原型}function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"];}SuperType.prototype.sayName = function(){alert(this.name);};function SubType(name, age){SuperType.call(this, name);this.age = age;}// 核心:因为是对父类原型的复制,所以不包含父类的构造函数,也就不会调用两次父类的构造函数造成浪费inheritPrototype(SubType, SuperType);SubType.prototype.sayAge = function(){alert(this.age);}

优缺点:这是一种完美的继承方式。

七、ES6 Class extends

核心: ES6继承的结果和寄生组合继承相似,本质上,ES6继承是一种语法糖。但是,寄生组合继承是先创建子类实例this对象,然后再对其增强;而ES6先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

class A {}class B extends A {constructor() {super();}}ES6实现继承的具体原理:class A {}class B {}Object.setPrototypeOf = function (obj, proto) {obj.__proto__ = proto;return obj;}// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);// B 继承 A 的静态属性
Object.setPrototypeOf(B, A);

ES6继承与ES5继承的异同:

相同点:本质上ES6继承是ES5继承的语法糖。

不同点:

  • ES6继承中子类的构造函数的原型链指向父类的构造函数,ES5中使用的是构造函数复制,没有原型链指向。

  • ES6子类实例的构建,基于父类实例,ES5中不是。

【JS继承】常见的7种继承方式相关推荐

  1. JS中常见的几种继承

    1原型链继承 子类构造函数.prototype = 父类的实例; 子类构造函数.prototype.constructor = 子类构造函数 特点: 1.js继承是把父类的原型放到子类的原型链上,实例 ...

  2. JS之常见的几种输出方式

    第一种 alert alert()浏览器的提示框(只有一个确定按钮). 在alert输出方式中,输出内容都是以字符串格式进行输出的,执行方式是,先将alert括号里面的内容转换成字符串格式的,然后再进 ...

  3. JS 跨域问题常见的五种解决方式

    JS 跨域问题常见的五种解决方式 一.什么是跨域? 要理解跨域问题,就先理解好概念.跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本只能读取来自同一来 ...

  4. 锚链常见的几种连接方式

    锚链常见的几种连接方式 有档锚链由锚端链节.末端链接和若干中间链节组成,链节与链节之间用连接卸扣连接. 常用连接方式如下 锚端链节 1.普环(Common Link,C)+......+普环(Comm ...

  5. 【温故知新】——原生js中常用的四种循环方式

    一.引言 本文主要是利用一个例子,讲一下原生js中常用的四种循环方式的使用与区别: 实现效果: 在网页中弹出框输入0   网页输出"欢迎下次光临" 在网页中弹出框输入1   网页输 ...

  6. 安川伺服总线通讯方式_plc通讯方式有哪三种?plc常见的三种通讯方式

    原标题:plc通讯方式有哪三种?plc常见的三种通讯方式 PLC = Programmable Logic Controller,可编程逻辑控制器,一种数字运算操作的电子系统,专为在工业环境应用而设计 ...

  7. 吐血整理!程序员常见的几种变现方式!

    今天聊一个特俗但是大家都想的事情, 那就是「赚钱」这件事. 先说为什么这个事情「特俗」,因为其实我发现我身边大部分程序员不爱谈钱,或者羞于谈钱. 加上程序员工资普遍比较高,所以早期都没啥压力,但是随着 ...

  8. js中数组的几种循环方式

    js中数组的几种循环方式 for循环最基本的循环方式,不多说.这种最基本的循环才是速度最快的,效率最高的. for(var i = 0;i<5;i++){console.log(i) } for ...

  9. PCBA加工中常见的两种焊接方式详解

    PCBA加工中常见的两种焊接方式详解 PCBA加工,两种常见的焊接方式就是回流焊和波峰焊,与手动焊接技术相比,自动焊接技术具有减少人为因素的影响.提高效率.降低成本.提高质量等优势,在PCBA加工中, ...

最新文章

  1. Python 工匠:在边界处思考
  2. 使用gdbserver远程调试
  3. python制作射击游戏_用python3从零开始开发一款烧脑射击游戏#2
  4. List集合的特有功能概述
  5. Storm【技术文档】-Worker Executor Task的关系
  6. 深度学习与计算机视觉(二)线性SVM与Softmax分类器
  7. Java Persistence API:快速入门
  8. jqc3ff继电器引脚图_单片机控制继电器驱动电路图原理分析
  9. python使用如下方法规范化数组_python归一化多维数组的方法
  10. Kubernetes群集的零停机服务器更新
  11. HDU2006 求奇数的乘积【入门】
  12. The Windows Phone Emulator wasn't able to create the external network switches 解决方法
  13. jq 遍历map集合
  14. VMware端口映射
  15. C语言数字图像处理---1.6图像亮度对比度调节
  16. js的alert弹框中怎么写html,JavaScript实现alert弹框效果
  17. mojave 未能与恢复服务器,Clover引导安装黑苹果卡各种问题的解决方法(内容较多)...
  18. 基于TCP的简单服务器
  19. 这十个嵌入式工程师最青睐的树莓派扩展板让你受用半生
  20. 预告:年度乘用车前装超声波雷达市场,哪些供应商表现抢眼

热门文章

  1. C++文件操作——创建和删除文件夹
  2. wxpy识别语音消息
  3. ajax 跳转 html页面传值,ajax实现页面跳转并传参
  4. LeetCode 1. 两数之和
  5. 淡奶油怎么打发 淡奶油打发技巧分享
  6. 经典又耐人寻味的一组冷笑话
  7. oracle中varchar 和 nvarchar2的区别,Oracle中char,varchar,varchar2,nvarchar,nvarchar2的区别
  8. 高中关于人工智能方面的课题_高中《人工智能》范文5篇800字
  9. nkoj P3320【小挑战】丢失的珠子
  10. oracle 开机变慢,项目最近突然启动很慢,平均启动3分钟,求助