一、你必须知道的

1> 原型及原型链在继承中起到了关键的作用。所以你一定要理解他们。
2> 不会JS中的OOP,你也太菜了吧!(第一篇)

二、继承的6种方法

1> 原型链继承

原型链继承是通过创建Super的实例,并将该实例赋值给Sub.prototype来实现的。

实现的本质是:重写子类型的原型对象,代之以超类型的实例。

function Super(){this.name = 'JChen___';
}
Super.prototype.getSuperName = function(){return this.name;
}function Sub(){this.subname = 'JChen___son';
}
Sub.prototype = new Super(); //原型继承体现在这里
Sub.prototype.getSubName = function(){return this.subname;
}var instance = new Sub();

注意:此时instance.constructor现在指向的是Super的,这是因为Sub.prototype指向了Super.prototype,而Super.prototype.constructor = Super。

原型链的问题:类似于利用原型创建对象,原型共享的特性也是原型链继承的最大问题。

2> 借用构造函数继承

在解决原型中包含引用类型值所带来的问题的过程中,我们开始使用一种叫做借用构造函数的技术。

这种技术的基本思想相当简单:在子类型构造函数的内部调用超类型构造函数

这样一来,就会在新子类对象上执行超类函数中定义的所有对象初始化代码。结果,每个子类的实力都会有自己的超类中属性的副本了。

function Super2(name){this.colors = ['red', 'blue'];this.name = name;
}function Sub2(){Super2.call(this, 'JChen___2'); //借用构造函数技术体现在这里this.age = 29;
}var instance1 = new Sub2();
instance1.colors.push('black');
var instance2 = new Sub2();
instance2.colors.push('green');

借助构造函数继承的问题:

1): 方法都在构造函数中定义,无法复用。

2): 在超类型的原型中的方法对子类是不可见的。

3> 组合继承(原型+借用构造)

组合继承指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。

组合继承的思路:使用原型链实现对方法和属性的继承,通过借用构造函数实现对实例属性的继承。

function Super3(name){this.name = name;this.colors = ['red', 'blue'];
}
Super3.prototype.sayName = function(){return this.name;
}function Sub3(name, age) {Super3.call(this, name);this.age = age;
}
Sub3.prototype = new Super3(); //解决借用构造函数技术的缺点
Sub3.prototype.constructor = Sub3; //纠正原型继承改变了的构造函数
Sub3.prototype.sayAge = function(){return this.age;
}

组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,成为JavaScript中最常用的继承模式。

组合继承的问题:两次调用超类构造函数。

4> 原型式继承

原型式继承的思路:借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。

function object(o){ //原型式继承的关键function F(){}F.prototype = o;return new F();
}
var person = {name: 'JChen___4',colors: ['blue']
}
var person1 = object(person);
person1.name = 'JChen___4___2'
person1.colors.push('red');
var person2 = object(person);
person2.name = 'JChen___4___3';
person2.colors.push('green');

原型式继承的问题:同原型链一样,他也有共享的劣势。

5> 寄生式继承

寄生式继承的思路:创建一个仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再返回该对象

function createAnother(origin){ //寄生式继承的关键var clone = object(origin);clone.sayHi = function(){return 'Hi';};return clone;
}
var person = {name: 'JChen___4',colors: ['blue']
}
var person1 = createAnother(person);

寄生式继承的问题:像构造函数一样,由于不能做到函数的复用而降低效率。

6> 寄生组合式继承

寄生组合式继承:通过借用构造函数来借用属性,通过原型链的混成形式来继承方法。

其背后的思想是:不必为了指定子类型的原型而调用超类型的构造函数,我们需要的无非就是超类型的一个副本而已。

function object(o){function F(){}F.prototype = o;return new F();
}
function inheritProto(subType, superType){ //避免第一调用构造函数的关键var proto = object(superType.prototype);proto.constructor = subType;subType.prototype = proto;
}function Super6(name){this.name = name;this.colors = ['red', 'blue'];
}
Super6.prototype.sayName = function(){return this.name;
}function Sub6(name, age){Super6.call(this, name);this.age = age;
}inheritProto(Sub6, Super6);Sub6.prototype.sayAge = function(){return this.age;
}var instance1 = new Sub6('JChen___6', '12');
instance1.colors.push('black');

开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

三、总结

这就是JavaScript中的6种继承方式,如果大家能够画出每个继承的原型链关系图,那么继承就是小菜一碟了。

转载于:https://www.cnblogs.com/JChen666/p/3375894.html

不会JS中的OOP,你也太菜了吧!(第二篇)相关推荐

  1. js面向对象编程:this究竟代表什么?第二篇

    总觉得自己弄明确了js中this的含义.this总是指向调用方法的对象,作为方法调用,那么this就是指实例化的对象.但前几天自己写脚本却遇到了一个非常奇怪的问题. 代码例如以下: //内部对象Aut ...

  2. 解决xhtmlrenderer flying-saucer-pdf-itext5 生成pdf时html中table分页内容太多挤到第二页问题。

    使用 flying-saucer-pdf-itext5 生成pdf时html中table的行如果太高的话会被挤到第二页展示,导致第一页中空白一大块. 解决办法: 修改org.xhtmlrenderer ...

  3. qq列表展开多个html代码,JS仿QQ好友列表展开、收缩功能(第二篇)

    在上篇的基础上继续完善,点击一个li元素,其他li元素上的类名清除掉. 效果图如下所示: js: window.onload = function(){ var list = document.get ...

  4. JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解

    前  言 学过程序语言的都知道,我们的程序语言进化是从"面向机器".到"面向过程".再到"面向对象"一步步的发展而来.类似于汇编语言这样的面 ...

  5. js 中添加php数组元素,JS数组添加元素方法总结

    本篇文章介绍了如何向JS数组中添加新的元素,分别使用不同的几种方法去给JS数组添加元素,数组在JS中是很常用的数据类型之一,而对数组进行操作这是我们必会的基础之一. 下面我们来看一下有哪些方法可以对J ...

  6. 进阶学习js中的执行上下文

    在js中的执行上下文,菜鸟入门基础 这篇文章中我们简单的讲解了js中的上下文,今天我们就更进一步的讲解js中的执行上下文. 1.当遇到变量名和函数名相同的问题. var a = 10; functio ...

  7. html中div区域可以交叉引用,需要js中的交叉引用

    我有我的requirejs模块互相交叉引用和交互的问题.需要js中的交叉引用 第一模块将进行第二模块的价值观,为什么requirejs表现得像是什么? HTML: Edit Save JS: defi ...

  8. html仿qq最小化怎么实现,JS仿QQ好友列表展开、收缩功能(第一篇)

    JS仿QQ好友列表展开.收缩功能(第一篇) 发布时间:2020-10-17 14:20:03 来源:脚本之家 阅读:96 作者:erdouzhang 效果图如下所示: html: 我的好友 张三 李四 ...

  9. JS OOP -02 深入认识JS中的函数

    深入认识JS中的函数: 1.概述,认识函数对象 2.函数对象和其他内部对象的关系 3.将函数作为参数传递 4.传递给函数的隐含参数:arguments 5.函数的apply,call方法和length ...

最新文章

  1. 记录一个需求:折线图,要求指定年份每一天的记录
  2. 未来ui设计的发展趋势_2025年的未来UI趋势?
  3. Docker原理剖析
  4. ERP(进纯销)系统如何开发,各类型系统都应该怎么做?
  5. Spark性能优化的10大问题及其解决方案
  6. 判断是否是微信浏览器JavaScript代码
  7. Windows 10通过本地镜像离线安装.NET 3.5
  8. setupfactory安装程序设置开机自启动
  9. 苹果电脑Mac电脑使用心得M1芯片快捷键
  10. QT入门之布局 水平布局、垂直布局、表单布局、网格布局
  11. 【老九学堂】【初识C语言】编译过程
  12. 拆弹专家【爆改车间主任】学习笔记(2)小结
  13. TPS,MIS,DSS,ESS,临时表
  14. HBASE region简介
  15. 深度解析:电商直播基地运营及盈利模式
  16. 泰山OFFICE技术讲座:字体属性的上标研究1:上标是什么
  17. 家庭智能终端开发之蓝牙语言遥控器概念篇
  18. escape在sql语句中的作用
  19. Android SQLite 数据库存储
  20. 我靠,在网站上出现中文的乱码竟然这样解决的

热门文章

  1. gradle maven_Gradle vs Maven
  2. 2020计算机顶级大会_2020年顶级公司和专业人员将使用40多种Web工具和服务
  3. 迅捷cad_迅捷结构
  4. VS2012下创建QT5应用程序
  5. 未来人工智能的发展应该有哪些特征?
  6. python制作 whl 源文件,并制作本地pip源
  7. varnish在Debian9.4安装和配置
  8. 二叉树转换成森林amp;森林变成二叉树
  9. IOS的四种数据存储方式及优劣
  10. 轻松背后的N+疲惫——系统日志