我们的JavaScript比较特别了,主要通过原型链实现继承的。

下面介绍各种实现继承的方式:原型链继承,借用构造函数,组合继承,原型式继承,寄生式继承,寄生组合式继承。

二、实现继承方式

1.原型链方式

原型我们都知道,每个构造函数都有一个原型对象(prototype),用于存放共享的属性方法。

原型链继承原理:我们要继承一个父类,那就把这个子类的原型对象指向父类的实例就行了。

a.代码:

b.一些特别注意的地方:

  1. 上面我们看到为子类原型添加方法getName,它在子类原型对象指向父类实例后,也一定要在这句话后面,如果在前面的话,这方法会被覆盖的。因为子类原型对象指向父类实例时相当于重写子类原型对象。

  2. 为子类原型添加方法式不能用字面量的方式,这样会重写已经继承类父类的原型对象。

c.原型链继承的问题:

很明显的,继承的属性方法都在子类的原型对象里面,那么里面的属性方法都是共享的,这明显不是符合我们平常要求。

2.借用构造函数

借?是的,借一下父类的构造函数,怎么借?那就使用call或者apply方法吧。

借用构造函数原理: 就在子类创建构造函数时内部调用父类的构造函数。

代码演示:

这里的借用构造函数可以实现属性和方法不会被共享,因为属性在构造函数中,而不是在原型对象中。但是这也说明这种方式没办法共享方法的。

3.组合继承(最常用)

组合继承=原型链继承+借用构造函数继承,没错就结合两种方法就好了。

组合继承原理:实例共享的属性方法:我就原型链继承;实例私用的属性方法:我就借用构造函数(结合两者的优点)

代码演示:

可能有的疑惑:在原型链继承那里,子类原型对象指向类父类的实例,应该继承了所有的属性和方法啊,那应该都是共享的,但为什么colors,name属性不会共享呢?

原因:在调用借用构造函数时,属性在子类新实例中创建了,也就是在子类实例中已经有的父类属性就不用继续到原型对象中查找了,也就是屏蔽了,所以不会共享了。

4.原型式继承

这是道格拉斯·克罗克福提出的一个方式,他提出一个函数object() 来简单实现不用构造函数的继承

代码演示:

认真读这段代码可以知道,这个函数最终返回一个对象,这个对象拥有传入对象o的全部属性和方法。从而实现了继承。

原型式继承方式的出现,可以不用创建构造函数都能继承另一个对象的属性方法。但是很明显,所用属性都是共享的。

ES5中有个object.create()方法的作用和上面的object()一样的。

5.寄生式的继承

寄生式其实和利用了原型式,都要使用到object函数,但不同的是寄生式中新的对象能够添加自己的方法。

6.寄生组合式继承(最理想)

上面组合式方式中虽然是最常用的,但有追求的还是会继续优化它。因为组合方式中也有不够好的地方:

一方面:我们可以看到调用了两次父类的构造函数。(一次是原型链继承中子类原型对象指向父类实例时,一次是借用构造函数中)

另一方面:就是上面疑惑,子类的原型中拥有父类已经有全部属性,但我们又要在调用子类构造函数时重写部分属性。

所以寄生组合方式就解决了上面,通过一个函数来代替组合方式中的原型链继承。

代码演示:

寄生组合式的继承方式是最理想的方式,它使得子类构造函数继承父类构造函数的属性,子类的原型对象继承父类原型对象的属性和方法。

javascript 的继承的更多相关文章

  1. Javascript模拟继承(赠送.net吐槽一段)

    首先吐槽一句,今年的就业形势很不乐观啊,特别是搞.net的(相对java),特特别是还没出校门没有正式工作经验的,找个实习很难,前些天接了个面试电话,上来就质疑我“你一个在校大学生怎么可能做了那么多项 ...

  2. 详解Javascript的继承实现(二)

    上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...

  3. JavaScript之继承(原型链)

    JavaScript之继承(原型链) 我们知道继承是oo语言中不可缺少的一部分,对于JavaScript也是如此.一般的继承有两种方式:其一,接口继承,只继承方法的签名:其二,实现继承,继承实际的方法 ...

  4. javascript深度克隆与javascript的继承实现

    1.javascript深度克隆: //注意这里的对象包括object和array function cloneObject(obj){ var o = obj.constructor === Arr ...

  5. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  6. TDD测试驱动的javascript开发(3) ------ javascript的继承

    说起面向对象,人们就会想到继承,常见的继承分为2种:接口继承和实现继承.接口继承只继承方法签名,实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承. ...

  7. 彻底理解Javascript原型继承

    彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...

  8. Javascript原型继承容易忽略的错误

    编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...

  9. JavaScript类继承, 用什么方法好

    JavaScript类继承, 用什么方法好 一个实例: 基类Car: function Car(color, year) { this.name = "car"; this.col ...

  10. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

随机推荐

  1. springboot使用zookeeper(curator)实现注册发现与负载均衡

    最简单的实现服务高可用的方法就是集群化,也就是分布式部署,但是分布式部署会带来一些问题.比如: 1.各个实例之间的协同(锁) 2.负载均衡 3.热删除 这里通过一个简单的实例来说明如何解决注册发现和负 ...

  2. 使用olami sdk实现一个语音查询股票的iOS程序

    前言 在目前的软件应用中,输入方式还是以文字输入方式为主,但是语音输入的方式目前应用的越来越广泛.在这里介绍一个使用 Olami SDK 编写的一个使用语音输入查询股票的APP Olami SDK的介 ...

  3. win10 uwp 读取文本GBK错误

    本文讲的是解决UWP文本GBK打开乱码错误,如何去读取GBK,包括网页GBK.最后本文给出一个方法追加文本. 我使用NotePad记事本保存文件,格式ASCII,用微软示例打开文件方式读取,出现错误 ...

  4. 二:Linux 的基本命令、VI编辑器、Linux中软件安装

    Linux 的基本命令 1. 文件操作 a) Windows 是多根的文件系统,物理上是 1 到多块硬盘,逻辑上分为 C.D.E--盘, 每个盘都是一棵树.Linux 是单根的文件系统,不分 CDE ...

  5. 在HTM中显示播放视频

    注意:video中source 源文件地址src替换成你的video路径<html>    <button onclick="playPause();">播 ...

  6. 基于8211lib库对s57电子海图的解析和存储

    电子海图是为适用航海需要而绘制的包含海域地理信息和航海信息的一种数字化的专题地图,符合国际标准的电子海图数据统称为S-57电子海图.本文主要在S-57电子海图数据的理论模型和数据结构的基础上,实现对S ...

  7. 学web前端开发写给新手的建议,超实用!

    01 前面的话 如今我们使用的互联网,客户端与服务器端的交互无时无刻不在发生.比如我们在浏览器打开网页,浏览器就是客户端,将网页数据发过来的也就是服务器.其实服务器,并没有什么特别的,也就是一台昼夜不 ...

  8. RabbitMQ 笔记-基本概念

    ConnectionFactory.Connection.Channel ConnectionFactory.Connection.Channel,这三个都是RabbitMQ对外提供的API中最基本的 ...

  9. R学习笔记 第四篇:函数,分支和循环

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  10. oracle赋值问题(将同一表中某一字段赋值给另外一个字段的语句)

    将同一表中某一字段赋值给另外一个字段的语句update jxc_ckmx ckmx1 set ckmx1.ddsl = (select ckmx2.sl from jxc_ckmx ckmx2 whe ...