继承以及Super
栏目: JavaScript · 发布时间: 6年前
内容简介:一个小小的总结,主要关注以下三个问题:ES5的继承方式,ES5的继承与ES6的继承的区别,ES6的super的几种使用方式以及其中this的指向。From
一个小小的总结,主要关注以下三个问题:ES5的继承方式,ES5的继承与ES6的继承的区别,ES6的super的几种使用方式以及其中this的指向。
一、ES5的继承
MDN | Object.create | 用 Object.create
实现类式继承
继承可以分为对象实例的继承,类的继承
二、ES6的继承
Class B extends A { } 中的A可以是个class,还可以是个有prototype属性的函数
三、ES5继承与ES6继承的区别
-
this的区别
ES5 的继承,实质是先创造子类的实例对象
this
,然后再将父类的方法添加到this
上面(Parent.apply(this)
)。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this
上面(所以必须先调用super
方法),然后再用子类的构造函数修改this
。 -
原型链ES6有两条
class A { } class B extends A { } B.__proto__ === A // true B.prototype.__proto__ === A.prototype // true
这样的结果是因为,类的继承是按照下面的模式实现的。
class A { } class B { } // B 的实例继承 A 的实例 Object.setPrototypeOf(B.prototype, A.prototype); // B 继承 A 的静态属性 Object.setPrototypeOf(B, A); const b = new B(); //setPrototypeOf的内部实现 Object.setPrototypeOf = function (obj, proto) { obj.__proto__ = proto; return obj; } //但是setPrototypeOf会有性能问题,通常推荐使用Object.create
-
ES6可以继承原生构造函数,而ES5不能
- 原生构造函数有:Boolean()、Number()、String()、Array()、Date()、Function()、RegExp()、Error()、Object()
-
原因:
-
ES5 是先新建子类的实例对象
this
,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数。 -
ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象
this
,然后再用子类的构造函数修饰this
,使得父类的所有行为都可以继承。
-
-
继承
Object
的子类,有一个 行为差异 。class NewObj extends Object{ constructor(){ super(...arguments); } } var o = new NewObj({attr: true}); o.attr === true // false
上面代码中,
NewObj
继承了Object
,但是无法通过super
方法向父类Object
传参。这是因为 ES6 改变了Object
构造函数的行为,一旦发现Object
方法不是通过new Object()
这种形式调用,ES6 规定Object
构造函数会忽略参数。
四、ES6的super及其this
-
作为函数:在子类构造函数中调用
super()
,super相当于父类constructor -
作为对象:
-
在子类 构造函数或普通函数 中使用
super.methodA()
,super相当于父类原型此时methodA中的this指向子类实例
-
在子类 静态方法 中使用
super.methodB()
,super指向父类而非原型,此时的methodB指的是父类的静态方法methodB此时methodB中的this指向子类,所以只能通过this访问到子类的静态方法和属性
-
-
在子类中使用super 给属性赋值
super.father_prop = 1
,相当于子类的thisthis.father_prop=1
class A { constructor() { this.x = 1; } } class B extends A { constructor() { super(); this.x = 2; super.x = 3; console.log(super.x); // undefined console.log(this.x); // 3 } change(){ super.x = 4 console.log(super.x); //undefined console.log(this.x); // 4 } } let b = new B(); b.change()
-
使用
super
的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。class A {} class B extends A { constructor() { super(); console.log(super); // 报错 } }
以上所述就是小编给大家介绍的《继承以及Super》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Practical Vim, Second Edition
Drew Neil / The Pragmatic Bookshelf / 2015-10-31 / USD 29.00
Vim is a fast and efficient text editor that will make you a faster and more efficient developer. It’s available on almost every OS, and if you master the techniques in this book, you’ll never need an......一起来看看 《Practical Vim, Second Edition》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
UNIX 时间戳转换
UNIX 时间戳转换