位置: 编程技术 - 正文

ES6 javascript中Class类继承用法实例详解

编辑:rootadmin

推荐整理分享ES6 javascript中Class类继承用法实例详解,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

本文实例讲述了ES6 javascript中Class类继承用法。分享给大家供大家参考,具体如下:

1. 基本用法

Class 之间可以通过extends关键字实现继承, 这比 ES5 的通过修改原型链实现继承, 要清晰和方便很多。

上面代码定义了一个ColorPoint类, 该类通过extends关键字, 继承了Point类的所有属性和方法。 但是由于没有部署任何代码, 所以这两个类完全一样, 等于复制了一个Point类。 下面, 我们在ColorPoint内部加上代码。

上面代码中, constructor方法和toString方法之中, 都出现了super关键字, 它在这里表示父类的构造函数, 用来新建父类的this对象。

子类必须在constructor方法中调用super方法, 否则新建实例时会报错。 这是因为子类没有自己的this对象, 而是继承父类的this对象, 然后对其进行加工。 如果不调用super方法, 子类就得不到this对象。

上面代码中, ColorPoint继承了父类Point, 但是它的构造函数没有调用super方法, 导致新建实例时报错。

ES5 的继承, 实质是先创造子类的实例对象this, 然后再将父类的方法添加到this上面( Parent.apply(this))。 ES6 的继承机制完全不同, 实质是先创造父类的实例对象this( 所以必须先调用super方法), 然后再用子类的构造函数修改this。

如果子类没有定义constructor方法, 这个方法会被默认添加, 代码如下。 也就是说, 不管有没有显式定义, 任何一个子类都有constructor方法。

另一个需要注意的地方是, 在子类的构造函数中, 只有调用super之后, 才可以使用this关键字, 否则会报错。 这是因为子类实例的构建, 是基于对父类实例加工, 只有super方法才能返回父类实例。

上面代码中, 子类的constructor方法没有调用super之前, 就使用this关键字, 结果报错, 而放在super方法之后就是正确的。

下面是生成子类实例的代码。

上面代码中, 实例对象cp同时是ColorPoint和Point两个类的实例, 这与 ES5 的行为完全一致。

2. 类的 prototype 属性和 __proto__ 属性

大多数浏览器的 ES5 实现之中, 每一个对象都有__proto__属性, 指向对应的构造函数的 prototype 属性。 Class 作为构造函数的语法糖, 同时有prototype 属性和__proto__属性, 因此同时存在两条继承链。

( 1) 子类的__proto__属性, 表示构造函数的继承, 总是指向父类。( 2) 子类prototype属性的__proto__属性, 表示方法的继承, 总是指向父类的prototype属性。

上面代码中, 子类B的__proto__属性指向父类A, 子类B的prototype属性的__proto__属性指向父类A的prototype属性。

这样的结果是因为, 类的继承是按照下面的模式实现的。

《对象的扩展》 一章给出过Object.setPrototypeOf方法的实现。

因此, 就得到了上面的结果。

这两条继承链, 可以这样理解: 作为一个对象, 子类( B) 的原型( __proto__属性) 是父类( A); 作为一个构造函数, 子类( B) 的原型( prototype属性) 是父类的实例。

3. Extends 的继承目标

extends关键字后面可以跟多种类型的值。

上面代码的A, 只要是一个有prototype属性的函数, 就能被B继承。 由于函数都有prototype属性( 除了Function.prototype函数), 因此A可以是任意函数。

下面, 讨论三种特殊情况。

第一种特殊情况, 子类继承 Object 类。

这种情况下, A其实就是构造函数Object的复制, A的实例就是Object的实例。

第二种特殊情况, 不存在任何继承。

这种情况下, A 作为一个基类( 即不存在任何继承), 就是一个普通函数, 所以直接继承Funciton.prototype。 但是, A调用后返回一个空对象( 即Object实例), 所以A.prototype.__proto__指向构造函数( Object) 的prototype属性。

第三种特殊情况, 子类继承null。

ES6 javascript中Class类继承用法实例详解

这种情况与第二种情况非常像。 A也是一个普通函数, 所以直接继承Funciton.prototype。 但是, A 调用后返回的对象不继承任何方法, 所以它的__proto__指向Function.prototype, 即实质上执行了下面的代码。

4. Object.getPrototypeOf()

Object.getPrototypeOf方法可以用来从子类上获取父类。

因此, 可以使用这个方法判断, 一个类是否继承了另一个类。

5. super 关键字

super这个关键字, 有两种用法, 含义不同。

( 1) 作为函数调用时( 即super(...args)), super代表父类的构造函数。

( 2) 作为对象调用时( 即super.prop或super.method()), super代表父类。 注意, 此时super即可以引用父类实例的属性和方法, 也可以引用父类的静态方法。

上面代码中, 子类通过super关键字, 调用父类实例的_p属性。由于, 对象总是继承其他对象的, 所以可以在任意一个对象中, 使用super关键字。

6. 实例的 __proto__ 属性

子类实例的 __proto__ 属性的 __proto__ 属性, 指向父类实例的 __proto__ 属性。 也就是说, 子类的原型的原型, 是父类的原型。

上面代码中, ColorPoint继承了Point, 导致前者原型的原型是后者的原型。

因此, 通过子类实例的__proto__.__proto__属性, 可以修改父类实例的行为。

上面代码在ColorPoint的实例p2上向Point类添加方法, 结果影响到了Point的实例p1。

原生构造函数的继承

原生构造函数是指语言内置的构造函数, 通常用来生成数据结构。 ECMAScript 的原生构造函数大致有下面这些。

以前, 这些原生构造函数是无法继承的, 比如, 不能自己定义一个Array的子类。

上面代码定义了一个继承 Array 的MyArray类。 但是, 这个类的行为与Array完全不一致。

之所以会发生这种情况, 是因为子类无法获得原生构造函数的内部属性, 通过Array.apply() 或者分配给原型对象都不行。 原生构造函数会忽略apply方法传入的this, 也就是说, 原生构造函数的this无法绑定, 导致拿不到内部属性。

ES5 是先新建子类的实例对象this, 再将父类的属性添加到子类上, 由于父类的内部属性无法获取, 导致无法继承原生的构造函数。 比如, Array 构造函数有一个内部属性[[DefineOwnProperty]], 用来定义新属性时, 更新length属性, 这个内部属性无法在子类获取, 导致子类的length属性行为不正常。

下面的例子中, 我们想让一个普通对象继承Error对象。

上面代码中, 我们想通过Error.call(e) 这种写法, 让普通对象e具有Error对象的实例属性。 但是, Error.call() 完全忽略传入的第一个参数, 而是返回一个新对象, e本身没有任何变化。 这证明了Error.call(e) 这种写法, 无法继承原生构造函数。

ES6 允许继承原生构造函数定义子类, 因为 ES6 是先新建父类的实例对象this, 然后再用子类的构造函数修饰this, 使得父类的所有行为都可以继承。 下面是一个继承Array的例子。

上面代码定义了一个MyArray类, 继承了Array构造函数, 因此就可以从MyArray生成数组的实例。 这意味着, ES6 可以自定义原生数据结构( 比如Array、 String 等) 的子类, 这是 ES5 无法做到的。

上面这个例子也说明, extends关键字不仅可以用来继承类, 还可以用来继承原生的构造函数。 因此可以在原生数据结构的基础上, 定义自己的数据结构。 下面就是定义了一个带版本功能的数组。

上面代码中, VersionedArray结构会通过commit方法, 将自己的当前状态存入history属性, 然后通过revert方法, 可以撤销当前版本, 回到上一个版本。 除此之外, VersionedArray依然是一个数组, 所有原生的数组方法都可以在它上面调用。

下面是一个自定义Error子类的例子。

注意, 继承Object的子类, 有一个行为差异。

上面代码中, NewObj继承了Object, 但是无法通过super方法向父类Object传参。 这是因为 ES6 改变了Object构造函数的行为, 一旦发现Object方法不是通过new Object() 这种形式调用, ES6 规定Object构造函数会忽略参数。

更多相关内容可查看本站专题:《ECMAScript6(ES6)入门教程》、《JavaScript数组操作技巧总结》、《JavaScript字符与字符串操作技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript错误与调试技巧总结》及《javascript面向对象入门教程》

希望本文所述对大家基于ECMAScript的程序设计有所帮助。

JavaScript Date对象应用实例分享 本文实例为大家分享了jsDate对象应用3个实例,供大家参考,具体内容如下一.获取日期时间,秒数实时跳动!DOCTYPEhtmlhtmllang="en"headmetacharset="UTF-8"titledate/

JavaScript数组push方法使用注意事项 js数组的push方法,想必大家都知道是向数组末尾添加元素,但是有一个很关键的点需注意:引自MDN返回值当调用该方法时,新的length属性值将被返回。va

微信小程序商品详情页规格属性选择示例代码 detail.wxml展示页面!--轮播图--swiperclass="swiper"indicator-dots="{{indicatorDots}}"autoplay="{{autoplay}}"interval="{{interval}}"duration="{{duration}}"circular="{{circular}}"blockwx:for="{{pi

标签: ES6 javascript中Class类继承用法实例详解

本文链接地址:https://www.jiuchutong.com/biancheng/369678.html 转载请保留说明!

上一篇:移动端网页开发调试神器Eruda的介绍与使用技巧(移动端网页开发技术)

下一篇:JavaScript Date对象应用实例分享(javascript date format)

  • 承兑汇票用开发票吗
  • 转让土地使用权营业税税率
  • 坏账损失核算的两种方法
  • 小汽车折旧年限的最新规定2023
  • 库存股增加为什么资产减少
  • 成本核算的三种基本方法
  • 减免的附加税怎么做会计分录
  • 红字信息表跨月撤销和申报
  • 民办非企业单位设立分机构
  • 计提和缴纳企业所得税分录
  • 二房东转租如何办理营业执照
  • 银行 收美金
  • 服装厂委托物资零散加工成品如何做账呢?
  • 城市建设综合配套费征收管理办法
  • 补缴所得税要调账吗
  • 收到外币货款的汇率
  • 签订设备维修合同会计分录
  • 待处理财产损益科目
  • 企业税前扣除凭证包括以下哪些方面
  • 社保基数每个月可以调整一次吗
  • 企业银行保证金账户怎么查询
  • 产业扶持周转金退回多久到账
  • 小规模企业增值税税率是多少
  • 小规模纳税人免税额度是多少
  • 公司 期货投资
  • 内外账合并步骤
  • 预付账款供应商类别怎么填
  • 培训费发票模板
  • 缴纳当月增值税30000元
  • 收到服务费计入什么科目
  • 封装和调用
  • thinkphp3.2框架
  • 报表重分类和不重分类
  • api使用方法
  • vue前端框架搭建
  • wordpress标签tag文章
  • 什么是资产减值准备计提
  • 非税收入定额票据可以报销吗去什么地方报销
  • 账实不符的后果和对策
  • mysql读写分离amoeba
  • 织梦的首页怎么换图片
  • mysql的基本介绍
  • 差旅费报销会计凭证
  • 销项负数会计分录怎么写
  • 收到法人投资款需要什么手续
  • 临时工工资应计入什么科目
  • 个人所得税如何计算
  • 退款扣除手续费
  • 企业的专利收费是多少
  • 印花税计入哪个会计分录
  • 加盟费收入需要纳税吗
  • 取得房租发票的租赁费可以抵税吗
  • 车间成本核算表
  • 建立明细账的操作步骤
  • 医疗机构药库设置标准
  • sql server 复制数据库具体操作图解
  • cndll.dll
  • win7 64位运行软件提示MSCOMCTL.OCX丢失或无效该怎么办?
  • windows10下软件的app
  • Ubuntu开启热点
  • win8命令提示符管理员怎么打开
  • ubuntu必备软件10款
  • linux 桌面系统
  • window98到windows10
  • linux防火墙放行
  • Win10 Mobile/PC/HoloLens一周年更新14389曝光
  • win10小娜无法启动语音识别
  • win7系统谷歌浏览器打不开网页
  • win8系统如何关机
  • opengl编程实例
  • 超级链接是什么意思
  • cmd怎么复制上一条命令快捷键
  • shell脚本编写 方法
  • unity资源包管理器
  • js表单事件有哪些
  • Activity的生命周期和页面之间的传递
  • android数据存储实验报告
  • High Level Networking Concepts
  • javascript模块化规范
  • 企业所得税
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设