一、原型链继承:基本思想是新建父类的实例,将父类的实例赋给子类的原型对象。这样,子类的原型对象中的 __proto__ 指针就指向父类的原型对象。再新建一个子类的实例,那么子类的实例就同时继承了子类和父类的原型对象中的属性和方法,从而实现了继承。所有引用类型都默认继承了 Object。具体实现:

function Super() {this.property = true;
}
Super.prototype.getSuperValue = function() {return this.property;
}function Sub() {this.subProperty = false;
}// 继承了父类
Sub.prototype = new Super();

原型链继承的缺点:引用类型的属性会被所有实例所共享,那么,修改一个实例的引用类型属性,也会影响另一个实例的引用类型属性。这个缺点出现的原因在于:Sub.prototype = new Super(); 子类实例指向的原型对象是 Sub.prototype,此时 Sub.prototype 已经是 Super 的实例了,如果父类的构造函数里面有 color 这个属性,那么 instance1 和 instance2 就共享这个 color 属性。所以,通过 instance1 修改这个属性,也会影响到 instance2。但是修改实例的值属性时,并不会影响原型和其他实例的值属性。

function Super() {this.colors = ["red", "blue"];
}function Sub() {}// 继承了父类
Sub.prototype = new Super();var instance1 = new Sub();
instance1.colors.push("black");
console.log(instance1.colors);   // ["red", "blue", "black"]var instance2 = new Sub();
console.log(instance2.colors);   // ["red", "blue", "black"]

解决方法,借用构造函数继承和组合继承

二、借用构造函数继承:基本思想是,在子类构造函数的内部,使用 call 方法调用超类构造函数。我们在将来要新建的 Sub 实例环境中调用了 Super 构造函数,这样一来,所有的Sub 实例都会有一份属于自己的 color 属性。

function Super() {this.colors = ["red", "blue"];
}function Sub() {Super.call(this);
}var instance1 = new Sub();
instance1.colors.push("black");
console.log(instance1.colors);   // ["red", "blue", "black"]var instance2 = new Sub();
console.log(instance2.colors);   // ["red", "blue"]

借用构造函数继承的缺点:方法都在构造函数中定义,那么函数复用就无从谈起了。解决办法,用组合继承(伪经典继承)

三、组合继承:基本思想,把原型继承和构造函数继承结合到一起,使用原型链对共有方法和属性的继承,使用构造函数对不共有属性的继承。是 JS 中常见的继承模式。

function Super() {this.colors = ["red", "blue"];
}Super.prototype.sayHello = function () {console.log("hello")
}function Sub() {// 继承不共享的属性和方法Super.call(this)
}// 继承共享的属性和方法
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
Sub.prototype.sayHi = function() {console.log("hi")
}var instance1 = new Sub();
instance1.colors.push("black");
console.log(instance1.colors);   // ["red", "blue", "black"]
instance1.sayHi();
instance1.sayHello();var instance2 = new Sub();
console.log(instance2.colors);   // ["red", "blue"]

组合式继承的缺点:会调用两次父类的构造函数。第一次是在子类构造函数中用 call 的方式调用,第二次是在继承原型链上的属性和方法,使用 new 来调用父类的构造函数。

四、组合继承的优化:基本思想是在子类的构造函数中依旧要用 call 方法,调用一遍父类的构造函数,依次来继承父类构造函数中的方法。但在继承父类原型对象中的方法就采用了,在子类和父类中间利用一个空对象来继承。把这个空对象的 prototype 属性复制成父类的构造函数,把子类的 prototype 属性复制成空对象的实例。

function SuperType() {this.color = ["red", "yellow", "blue"];
}SuperType.prototype.sayHello = function() {console.log("hello")
}// 继承父类的构造函数里面的属性
function SubType() {SuperType.call(this);this.friends = ["a", "b", "c"];
}// 继承父类原型对象的属性
// 道格拉斯的方法
// function object(o) {//     function F() {};
//     F.prototype = o;
//     return new F();
// }// es5 把上面的方法规范化了,变成了 Object.create(o)
SubType.prototype = Object.create(SuperType);// 把子类的 constructor 属性指向变回 SubType
SubType.prototype.constructor = SubType;

Object.create()和 new object()的区别

1. Object.create()方法是ECMAScript5中新增的,用来规范化原型式继承的。这个方法接收两个参数,一个是用作新对象原型的对象,和一个为新对象定义额外属性的(可选)对象。

new Object()方法的实质是,使用引用类型Object的构造函数创建了一个新的实例,这个实例拥有Object默认的方法如toString、toLocaleString等。

2. Object.create创建对象是创建一个拥有指定原型和若干个指定属性的对象,也就是说可以任意指定原型,甚至是null, 而new Object()只是创建了一个以Object.prototype为原型的对象。

转载于:https://www.cnblogs.com/rougan/p/10600591.html

JS 继承各种方法的优劣比较 ----JS 学习笔记(五)相关推荐

  1. js继承的方法及原理

    js继承的方法及原理 1.原型链继承 原理:父类的实例作为子类的原型 function Woman(){ } Woman.prototype= new People(); Woman.prototyp ...

  2. 2020年高等数学方法与提高(上海理工大学)学习笔记汇总

    写在前面: [1] 本系列文章涉及内容已与授课教师联系,已获得许可.如有不妥之处,请联系博主740925018@qq.com. [2] 对授课教师表示衷心感谢.贾老师的高等数学方法与提高.数学分析等课 ...

  3. 计算机视觉——一种现代方法(第二版)学习笔记

    计算机视觉--一种现代方法(第二版)学习笔记 第1章 摄像机的几何模型 如上左图所示,我们需要将一个空间点X映射到一个图像点x(3维->2维)上即 根据右上图我们很容易推到处下面的变换: 这个结 ...

  4. 加mp4文件后js失效_Jquery方法load之后导致js失效解决方法

    Jquery方法load之后导致js失效解决方法 >>>>>>>>>>>>>>>>>>> ...

  5. android js接口调用方法,详解Android JS相互调用

    最近在研究Android.JS相互调用,之前没怎么接触过,只知道loadUrl()就可以加载一个网页了,研究过之后发现Android可以调JS,JS也可以调Android原生控件,很开心啊.下面小编就 ...

  6. js调用后台方法与后台调用js方法

    JS调用后台方法大全 javascript函数中执行C#代码中的函数: 方法一:1.首先建立一个按钮,在后台将调用或处理的内容写入button_click中; 2.在前台写一个js函数,内容为docu ...

  7. 原生JS零魂之问(上)学习笔记‍

    作为一个普通的JS初学者,从神三元大佬的知识梳理文章中受益匪浅,写下我的学习笔记吧. JS数据类型 function test(person) {person.age = 26person = {na ...

  8. Vue.js 学习笔记 五 常用的事件修饰符

    介绍几个常用的事件修饰符 直接上代码 <div id="divApp"><div class="divColor" v-on:click=&q ...

  9. 2020年高等数学方法与提高(上海理工大学)学习笔记:一元函数积分学

    写在前面: [1] 本系列文章涉及内容已与授课教师联系,已获得许可.如有不妥之处,请联系博主740925018@qq.com. [2] 请读者尊重知识产权,尊重授课教师的成果. [3] 对读者表示感谢 ...

最新文章

  1. 初学Python的学习笔记7----偏函数、模块、重点是面向对象
  2. 数据结构与算法(C语言) | 栈和队列——栈(自己做过测试)
  3. cisco路由器基本实验之九 PAT的配置(Packet Tracer)
  4. hive 两个没有null指定的表左关联的结果有null_Hive的优化原则
  5. linux创建文件内容三行,shell之创建文件及内容的方法示例
  6. sentinel控制台无数据解决
  7. Java虚拟机(五)——程序计数器
  8. 试用到期_各大化妆品品牌试用装广告
  9. 图像相减的matlab仿真及光栅滤波法,图像相减的MATLAB 仿真及光栅滤波法实验实现...
  10. java ocx调用_Javascript调用OCX控件
  11. 计算机软件行业各职位英文缩写
  12. 微信小程序实现自动登录
  13. 投影仪服务器响应失败,投影仪几种常见问题现象分析,投影仪故障问题
  14. 深入研究Clang(十六) Clang Driver库的ToolChain
  15. c语言sqart函数格式,2019-07-29 复习C语言入门知识
  16. 新一配:一篇看懂加油站产业链解决方案
  17. 耿建超英语语法---非谓语动词作同位语和定语
  18. 【STM32F429开发板用户手册】第33章 STM32F429的SPI总线应用之驱动DAC8563(双通道,16bit分辨率,正负10V)
  19. Nexus上传jar问题【史上最全,亲测可用】
  20. 老国企如何焕发新势能?致远互联“协同五环”锻造老而弥坚

热门文章

  1. centos8 安装mysql_Centos 离线安装mysql8(以及在线安装)
  2. python输出语句print i、j、k,python:在exec语句中获取打印输出
  3. python metaclass应用
  4. setuptools include_package_data
  5. 图解TCPIP-NAT
  6. Pandas GroupBy 分组(分割-应用-组合)
  7. C语言rand函数生成随机数详解和示例
  8. java中抛出异常快捷键_idea中处理异常的快捷键
  9. Windows Server 2016系统高级管理系列-DFS分布式文件系统
  10. Windows server 2016 安装补丁报错 - The update is not applicable to your computer Error:0x800f0823