好久没写博客啦,嘻嘻,这个月是2017年的最后一个月啦,大家应该都开始忙着写年终总结了吧,嘻嘻,小颖今天给大家分享下Javascript中的几种继承方式以及他们的优缺点。

1.借助构造函数实现继承

原理:通过call()函数修改 this 指向,从而实现将父类属性挂载到子类实例中。

    function parent1() {
this.name = 'parent1';
}
function child1() {
parent1.call(this);
this.type = 'child1';
}
console.log(new child1);

打印结果:

当我们给父类 parent1 的 prototype 属性添加say方法后,但是在 child1 中是获取不到的。

    function parent1() {
this.name = 'parent1';
}
parent1.prototype.say = function() {
console.log('hello');
}; function child1() {
parent1.call(this);
this.type = 'child1';
}
console.log(new child1, new child1().say());

打印结果:

所以.借助构造函数实现继承,只能实现部分继承;如果父类属性都在构造函数中,则能够实现全部继承,如果父类原型对象上还有方法,则子类是继承不到的。

总结:

优点:
           1.只调用一次父类的构造函数,避免了在子类原型上创建不必要的,多余的属性 。
           2.原型链保持不变。
     缺点:只能实现部分继承;如果父类属性都在构造函数中,则能够实现全部继承,如果父类原型对象上还有方法,则子类是继承不到的。

2.借助原型链实现继承(最通用的方式)

原理:将子类的prototype属性赋值为父类实例对象,则子类的_proto_属性继承父类。

    function parent2() {
this.name = 'parent2';
this.play = [1, 2, 3];
}
parent2.prototype.say = function() {
console.log('hello');
}; function child2() {
this.type = 'child2';
}
child2.prototype = new parent2();
console.log(new child2);
var p1 = new child2();
var p2 = new child2();
console.log(p1.say());
console.log(p1.play, p2.play);
p1.play.push(4);
console.log(p1, p2);
console.log(p1.play, p2.play);

打印结果:

注意:

1.在第一种继承方式中,子类是继承不到父类 prototype 属性的内容的,但现在可以继承到了。

2.其实小颖只执行了  p1.play.push(4)  ,然而 p2.play 的值也跟着变化了。

这其实都是因为   child2.prototype = new parent2(),他们的 __proto__ 都继承了父类parent2 的所有属性。虽然表面上  p1.play.push(4)   看起来像是只改变了 p1 的  play 属性,但其实是改变了父类  parent2 的 play 属性,而p1,p2继承了 parent2 ,所以p1,p2同时发生变化。

总结:

优点:父类的方法(getName)得到了复用。
     缺点:重写子类的原型 等于 父类的一个实例,(父类的实例属性变成子类的原型属性)如果父类包含引用类型的属性,那么子类所有实例都会共享该属性 (包含引用类型的*原型*属性会被实例共享)。

3.组合方式

    function parent3() {
this.name = 'parent3';
this.play = [1, 2, 3];
} function child3() {
parent3.call(this);
this.type = 'child3';
}
child3.prototype = new parent3();
var p3 = new child3();
var p4 = new child3();
console.log(p3.play, p4.play);
p3.play.push(4);
console.log(p3,p4);
console.log(p3.play, p4.play);

打印结果:

注意:

在上面的结果中,大家有没有发现,同样只给   p3.play.push(4) ,但是只有p3一个变了,但p4没有变,其实大家通过小颖用红框框起来的地方,大就会明白,为什么p3、p4的 __proto__ 都继承了父类parent2 的属性,为什么修改p3,p4,这次p4却没有变化。

总结:

优点:继承了上述两种方式的优点,摒弃了缺点,复用了方法,子类又有各自的属性。
     缺点:因为父类构造函数被执行了两次,子类的原型对象(Sub.prototype)中也有一份父类的实例属性,而且这些属性会被子类实例(sub1,sub2)的属性覆盖掉,也存在内存浪费。

4.组合继承的优化1

    function parent4() {
this.name = 'parent4';
this.play = [1, 2, 3];
} function child4() {
parent4.call(this);
this.type = 'child4';
}
child4.prototype = parent4.prototype;
var p5 = new child4();
var p6 = new child4();
console.log(p5, p6);
console.log(p5 instanceof child4, p5 instanceof parent4);
console.log(p5.constructor);

打印结果:

注意:

instanceof 和 constructor 都是用来判断一个实例对象是不是这个构造函数的实例的。
不同点是:用constructor 比instanceof 更严谨,例如如果 A 继承 B,B 继承 C,A 生成的实例对象,用 instanceof 判断与 A、B、C 的关系,都是 true。所以无法区分这个到底是 A、B、C 谁生成的实例。而constructor 是原型对象的一个属性,并且这个属性的值是指向创建当前实例的对象的。

console.log(p5 instanceof child4, p5 instanceof parent4); 执行结果一样,而且 p5.constructor 竟然不是 child4 而是 parent4。

5.组合继承的优化2 ——寄生组合式继承

   function parent5() {
this.name = 'parent5';
this.play = [1, 2, 3];
} function child5() {
parent5.call(this);
this.type = 'child5';
}
child5.prototype = Object.create(parent5.prototype);
child5.prototype.constructor = child5;
var p7 = new child5();
var p8 = new child5();
console.log(p7, p8);
console.log(p7.constructor);

打印结果:

总结:

组合继承的缺点就是在继承父类方法的时候调用了父类构造函数,从而造成内存浪费,并且找不到实例对象真正的 constructor 。

那在复用父类方法的时候,使用Object.create方法也可以达到目的,没有调用父类构造函数,并将子类的 prototype.constructor 属性赋值为自己本身,则问题完美解决。

JavaScript各种继承方式和优缺点的更多相关文章

  1. javascript中继承方式及优缺点(三)

    文以<JavaScript高级程序设计>上的内容为骨架,补充了ES6 Class的相关内容,从我认为更容易理解的角度将继承这件事叙述出来,希望大家能有所收获. 1. 继承分类 先来个整体印 ...

  2. javascript中继承方式及优缺点(一)

    分别介绍原型链继承.call/apply继承(借用构造函数继承).组合继承.原型式继承.寄生式继承.寄生组合式继承 1. 原型链继承 核心:将父类的实例作为子类的原型 function SuperTy ...

  3. javascript中继承方式及优缺点(二)

    一.原型链继承 方式1: 原型链继承 (1)流程: ​ 1.定义父类型构造函数. ​ 2.给父类型的原型添加方法. ​ 3.定义子类型的构造函数. ​ 4.创建父类型的对象赋值给子类型的原型. ​ 5 ...

  4. js各种继承方式和优缺点的介绍

    js各种继承方式和优缺点的介绍 作者: default 参考网址2 写在前面 本文讲解JavaScript各种继承方式和优缺点. 注意: 跟<JavaScript深入之创建对象>一样,更像 ...

  5. js的三种继承方式及其优缺点

    [转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...

  6. DOM笔记(十三):JavaScript的继承方式

    在Java.C++.C#等OO语言中,都支持两种继承方式:接口继承和实现继承.接口继承制继承方法签名,实现继承则继承实际的方法和属性.在SCMAScript中,由于函数没有签名,所以无法实现接口继承, ...

  7. JavaScript 六种继承方式

    title: JS的六种继承方式 date: 2017-06-27 05:55:49 tags: JS categories: 学习 --- 继承是面向对象编程中又一非常重要的概念,JavaScrip ...

  8. JavaScript各种继承方式(二):借用构造函数继承(constructor stealing)

    一 原理 在子类的构造函数中,通过call ( ) 或 apply ( ) 的形式,调用父类的构造函数来实现继承. function Fruit(name){ this.name = name; th ...

  9. javascript中各种继承方式的优缺点

    javascript中实现继承的方式有很多种,一般都是通过原型链和构造函数来实现.下面对各种实现方式进行分析,总结各自的优缺点. 一 原型继承 let Super = functioin(name = ...

随机推荐

  1. NIO FileChannel

    NIO提供了比传统的文件访问更好的访问方法,NIO有两个优化的方法:一个是 FIleChannel.transferTo FileChannel.transferFrom,另一个是FileChanne ...

  2. web开发|如何选择合适的webui框架

    在市场中很多人分不清框架和库的区别,部分只知道框架模糊的概念.所以在选择webUI框架的时候就会仁者见仁智者见智,会存在各抒己见也是很正常的,这里整体都叫框架吧,在市场中不断的淘汰与创新,主要以Vue ...

  3. Akka(33): Http:Marshalling,to Json

    Akka-http是一项系统集成工具.这主要依赖系统之间的数据交换功能.因为程序内数据表达形式与网上传输的数据格式是不相同的,所以需要对程序高级结构化的数据进行转换(marshalling or se ...

  4. WebSocket 详解教程

    WebSocket 详解教程 概述 WebSocket 是什么? WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 ...

  5. Web设计新手应知道的10个锦囊妙计

    摘要:你在网页设计所学到的大多数教训都来自工作经验.学习是一个反复持续的过程,并且没有比犯错更好的方式来获得知识.在本文中,我们将讨论10个重要并常规的技巧,这是每位Web设计师新手都应该知道. 在做 ...

  6. c语言的,三个工具可以使编译器生成性能更佳的代码。

    内联函数声明inline 函数有时可以非常短.短函数的每次调用可以用实现该函数功能的内联代码替代,以提高执行性能.意味着不需要给函数传递或返回一个值,要让编译器采用这种技术,可以把短函数指定为inli ...

  7. python抓去网页一部分

    import sys, urllib2 headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9. ...

  8. 【Win 10 应用开发】UI Composition 札记(三):与 XAML 集成

    除了 DirectX 游戏开发,我们一般很少单独使用 UI Composition ,因此,与 XAML 互动并集成是必然结果.这样能够把两者的优势混合使用,让UI布局能够更灵活. 说到与 XAML ...

  9. [译]移动API安全终极指南

    文章主要讲了移动api调用的授权和验证问题,原文链接:The Ultimate Guide to Mobile API Security 移动API的使用是Stack Overflow和 Stormp ...

  10. Layui框架+PHP打造个人简易版网盘系统

    网盘系统   大家应该都会注册过致命的一些网盘~如百度云.百科介绍:网盘,又称网络U盘.网络硬盘,是由互联网公司推出的在线存储服务,服务器机房为用户划分一定的磁盘空间,为用户免费或收费提供文件的存储. ...