es6中用class和extends关键字来实现继承。ES6中引入了class关键字来声明类, 而class(类)可通过extends关键字实现继承,让子类继承父类的属性和方法,语法“class 父类名{...} class 子类名 extends 父类名{...};”。
本教程操作环境:windows7系统、ECMAScript 6版、Dell G3电脑。
es6中可利用class关键字配合extends关键字来实现继承。
ES6 Class 的继承
1.简介
Class可以通过extends关键字实现继承,让子类继承父类的属性和方法。这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
//父类 class Point { ... } //子类 class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return this.color + '' + super.toString(); // 调用父类的toString方法 } }
上面代码中,constructor方法和toString方法内部,都出现了super关键字,super在这里表示父类的构造函数,用来新建一个父类的实例对象。
ES6规定,子类必须在constructor方法中调用super(),否则会报错,这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后在添加子类自己的实例属性和方法。
为什么子类的构造函数,一定要调用super()?
这是因为在ES5的继承机制中,是先创造一个独立的子类的实例对象,然后再将父类的方法添加到这个对象上,即“实例在前,继承在后”;ES6的继承机制,则是先将父类的属性和方法,加到一个空的对象上面,然后再将该对象作为子类的实例,即“继承在前,实例在后”。
这意味着,每次新建子类实例时,父类的构造函数必定会先运行一次
class Foo { constructor() { console.log(1); } } class Bar extends Foo { constructor() { super(); console.log(2); } } const bar = new Bar(); // 1 2
上面的代码中,子类Bar新建实例时,会输出1和2,这就是因子类构造函数调用super()时,会执行一次父类构造函数。只有在子类的构造函数中调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,必须先完成父类的继承,只有super方法才能让子类实例继承父类。
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { this.color = color; super(x, y); this.color = color; } }"
如果子类没有定义constructor方法,这个方法会默认添加,并且里面会调用super,也就是说,不管有没有显示定义,任何一个子类都有constructor方法.
class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8} class ColorPoint extends Point { constructor(...args) { super(...args); } } let cp = new ColorPoint(25, 8); console.log(cp); //{x: 25, y: 8}
2.私有属性和私有方法的继承
父类所有的属性和方法,都会被子类继承,除了私有的属性和方法。子类无法继承父类的私有属性,或者说私有属性只能在定义它的class里面使用。
class Foo { #p = 1; #m() { console.log('hello'); } } class Bar extends Foo { constructor() { super(); console.log(this.#p); // 报错 this.#m(); // 报错 } }
上面示例中,子类 Bar 调用父类 Foo 的私有属性或私有方法,都会报错。
如果父类定义了私有属性的读写方法,子类就可以通过这些方法,读写私有属性。
class Foo { #p = 1; getP() { return this.#p; } } class Bar extends Foo { constructor() { super(); console.log(this.getP()); // 1 } }
3.静态属性和方法的继承
父类的静态属性和静态方法,也会被子类继承。
class A { static hello() { console.log('hello world'); } } class B extends A { } B.hello() // hello world
上面代码中,hello()
是A
类的静态方法,B
继承A
,也继承了A
的静态方法。
注意,静态属性是通过浅拷贝实现继承的,如果继承的属性是原始数据类型,子类中操作继承的静态属性不会影响到父类,但如果继承的属性是一个对象,那么子类修改这个属性会印象到父类
class C { static foo = 100; } class D extends C { constructor() { super(); D.foo--; } } const d = new D(); C.foo; // 100 D.foo; // 99 class A { static foo = { n: 100 }; } class B extends A { constructor() { super(); B.foo.n--; } } const b = new B(); B.foo.n // 99 A.foo.n // 99
4.Object.getPrototypeOf()
Object.getPrototypeOf()
方法可以用来从子类上获取父类。
class Point { /*...*/ } class ColorPoint extends Point { /*...*/ } Object.getPrototypeOf(ColorPoint) === Point // true
因此,可以使用这个方法判断,一个类是否继承了另一个类。
5.super关键字
super关键字既可以当做函数使用,也可以当做对象使用
第一种情况,super作为函数调用时,代表父类的构造函数。调用super的作用是形成子类的this对象,把父类的实例属性和方法都放到这个this对象上面。
class A { constructor() { console.log(new.target.name); } } class B extends A { constructor() { super(); } } new A(); // A new B(); // B
第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
class A { p() { return 2; } } class B extends A { constructor() { super(); console.log(super.p()); // 2 } } let b = new B();
上面代码中,子类B中的super.p(),将super当做一个对象使用,这时super在普通对象中,指向的是A.prototype,super.p()相当于A.prototype.p()。
由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。如下所示:
class A { constructor() { this.p = 2; } } class B extends A { get m() { return spuer.p; } } let b = new B(); b.m // undefined
为了解决这种问题,可以将属性定义在父类的原型对象上
class A {}; A.prototype.x = 2; class B extends A { constructor() { super(); console.log(super.x); } } let b = new B();
ES6规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例
class A { constructor() { this.x = 1; } print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } m() { super.print(); } } let b = new B(); b.m(); // 2
上面代码中,super.print()调用的是A.prototype.print(),但是此时方法内部的this指向是子类B的实例,所以输出2。
由于this指向的是子类实例,所有如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性
class A { constructor() { this.x = 1; } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; console.log(super.x); //undefind console.log(this.x); // 3 } }
上面代码中,super.x
赋值为3
,这时等同于对this.x
赋值为3
。而当读取super.x
的时候,读的是A.prototype.x
,所以返回undefined
。
如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。
class Parent { static myMethod(msg) { console.log('static', msg); } myMethod(msg) { console.log('instance', msg); } } class Children extends Parent { static myMethod(msg) { super.myMthod(msg); } myMethod(msg) { super.myMethod(msg); } } Child.myMethod(1); // static 1 var child = new Child(); child.myMethod(2); // instance 2
上面代码中,super
在静态方法之中指向父类,在普通方法之中指向父类的原型对象。
另外,在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例
class A { constructor() { this.x = 1; } static print() { console.log(this.x); } } class B extends A { constructor() { super(); this.x = 2; } static m() { super.print(); } } B.x = 3; B.m() // 3
在静态方法m中,super.print指向父类的静态方法,到那时this指向的是类B,而不是B的实例。
【推荐学习:javascript高级教程】
以上是es6中用什么实现继承的详细内容。更多信息请关注PHP中文网其他相关文章!

HTML与React可以通过JSX无缝整合,构建高效的用户界面。1)使用JSX嵌入HTML元素,2)利用虚拟DOM优化渲染性能,3)通过组件化管理和渲染HTML结构。这种整合方式不仅直观,还能提升应用性能。

React通过state和props高效渲染数据,并通过合成事件系统处理用户事件。1)使用useState管理状态,如计数器示例。2)事件处理通过在JSX中添加函数实现,如按钮点击。3)渲染列表需使用key属性,如TodoList组件。4)表单处理需使用useState和e.preventDefault(),如Form组件。

React通过HTTP请求与服务器交互,实现数据的获取、发送、更新和删除。1)用户操作触发事件,2)发起HTTP请求,3)处理服务器响应,4)更新组件状态并重新渲染。

React是一种用于构建用户界面的JavaScript库,通过组件化开发和虚拟DOM提高效率。1.组件与JSX:使用JSX语法定义组件,增强代码直观性和质量。2.虚拟DOM与渲染:通过虚拟DOM和diff算法优化渲染性能。3.状态管理与Hooks:Hooks如useState和useEffect简化状态管理和副作用处理。4.使用示例:从基本表单到高级的全局状态管理,使用ContextAPI。5.常见错误与调试:避免状态管理不当和组件更新问题,使用ReactDevTools调试。6.性能优化与最佳

reactisafrontendlibrary,focusedonBuildingUserInterfaces.itmanagesuistateandupdatesefficefited fichifited firstualdom,以及EnternactSwithBackendServensEvesviaApisforDataHandling,butdoesnotprocessorsorstoredordordoredaiteffers。

React可以嵌入到HTML中来增强或完全重写传统的HTML页面。1)使用React的基本步骤包括在HTML中添加一个根div,并通过ReactDOM.render()渲染React组件。2)更高级的应用包括使用useState管理状态和实现复杂的UI交互,如计数器和待办事项列表。3)优化和最佳实践包括代码分割、惰性加载和使用React.memo和useMemo来提高性能。通过这些方法,开发者可以利用React的强大功能来构建动态和响应迅速的用户界面。

React是构建现代前端应用的JavaScript库。1.它采用组件化和虚拟DOM优化性能。2.组件使用JSX定义,状态和属性管理数据。3.Hooks简化生命周期管理。4.使用ContextAPI管理全局状态。5.常见错误需调试状态更新和生命周期。6.优化技巧包括Memoization、代码拆分和虚拟滚动。

React的未来将专注于组件化开发的极致、性能优化和与其他技术栈的深度集成。1)React将进一步简化组件的创建和管理,推动组件化开发的极致。2)性能优化将成为重点,特别是在大型应用中的表现。3)React将与GraphQL和TypeScript等技术深度集成,提升开发体验。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),