es6 super关键字
super关键字
super
这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。
第一种情况,super
作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super
函数。
class A {}
class B extends A {
constructor() {
super();
}
}
上面代码中,子类B
的构造函数之中的super()
,代表调用父类的构造函数。这是必须的,否则 JavaScript 引擎会报错。
注意,super
虽然代表了父类A
的构造函数,但是返回的是子类B
的实例,即super
内部的this
指的是B
,因此super()
在这里相当于A.prototype.constructor.call(this)
。
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
上面代码中,new.target
指向当前正在执行的函数。可以看到,在super()
执行时,它指向的是子类B
的构造函数,而不是父类A
的构造函数。也就是说,super()
内部的this
指向的是B
。
作为函数时,super()
只能用在子类的构造函数之中,用在其他地方就会报错。
class A {}
class B extends A {
m() {
super(); // 报错
}
}
上面代码中,super()
用在B
类的m
方法之中,就会造成句法错误。
第二种情况,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 super.p;
}
}
let b = new B();
b.m // undefined
上面代码中,p
是父类A
实例的属性,super.p
就引用不到它。
如果属性定义在父类的原型对象上,super
就可以取到。
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
上面代码中,属性x
是定义在A.prototype
上面的,所以super.x
可以取到它的值。
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()
,但是A.prototype.print()
内部的this
指向子类B
,导致输出的是2
,而不是1
。也就是说,实际上执行的是super.print.call(this)
。
由于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); // undefined
console.log(this.x); // 3
}
}
let b = new B();
上面代码中,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 Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
上面代码中,super
在静态方法之中指向父类,在普通方法之中指向父类的原型对象。
注意,使用super
的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。
class A {}
class B extends A {
constructor() {
super();
console.log(super); // 报错
}
}
上面代码中,console.log(super)
当中的super
,无法看出是作为函数使用,还是作为对象使用,所以 JavaScript 引擎解析代码的时候就会报错。这时,如果能清晰地表明super
的数据类型,就不会报错。
class A {}
class B extends A {
constructor() {
super();
console.log(super.valueOf() instanceof B); // true
}
}
let b = new B();
上面代码中,super.valueOf()
表明super
是一个对象,因此就不会报错。同时,由于super
使得this
指向B
,所以super.valueOf()
返回的是一个B
的实例。
最后,由于对象总是继承其他对象的,所以可以在任意一个对象中,使用super
关键字。
var obj = {
toString() {
return "MyObject: " + super.toString();
}
};
obj.toString(); // MyObject: [object Object]
es6 super关键字相关推荐
- es6 super 关键字
super 关键字 我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象. const proto = { foo: 'hello' ...
- ES6——super关键字
super关键字有两种使用场景 1.当用作方法时 在ES6的构造函数中,ES6的语法规定,在继承于父类的子类的构造函数中,必须使用super(),因为在子类中是不存在上下文指向(this)的,需要使用 ...
- ES6的 super 关键字
Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多. 子类必须在constructor方法中调用super方法,否则新建实例时会报错. 这是因为子 ...
- ES6 (二十二)Class 的继承、extends关键字、super 关键字(函数调用(constructor)、对象(父类原型对象))、原型对象(原型链)、Mixin 模式
ES6 (二十二)Class 的继承.extends关键字.super 关键字(函数调用(constructor).对象(父类原型对象)).原型对象(原型链).Mixin 模式 文章目录 ES6 (二 ...
- ES6 class关键字 ~ 非常详细
下面的对ES6中class关键字的整理,希望可以帮助到有需要的小伙伴~ 文章目录 类的声明 构造函数 getter与setter 不允许提前声明 不允许重复声明 静态方法 静态方法的语法 类的继承 实 ...
- JavaScript中解析super关键字
虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...
- This和Super关键字的对比
this和Super关键字 this和Super关键字的对比 Super关键字的用法如下: 1. super关键字代表了父类空间的引用: 2. super关键字的作用: 3. super关键字调用父类 ...
- Java基础学习总结(8)——super关键字
2019独角兽企业重金招聘Python工程师标准>>> 一.super关键字 在JAVA类中使用super来引用父类的成分,用this来引用当前对象,如果一个类从另外一个类继承,我们 ...
- Java面向对象之继承,方法重写,super关键字,员工类系列继承题
在程序中,如果想声明一个类继承另一个类,需要使用extends关键字. 格式: class 子类 extends 父类 {} 继承的好处 1.继承的出现提高了代码的复用性,提高软件开发效率. 2.继承 ...
最新文章
- Tomcat中出现“RFC 7230 and RFC 3986“错误的解决方法
- Excel组件DCOM配置
- STM32F4 HAL库开发 -- NVIC 中断优先级管理
- SAP Fiori Lead应用中Accept按钮显示隐藏的逻辑
- ElementUI 组件库 md-loader 的解析和优化
- dd命令iso linux_BootISO:从 ISO 文件中创建一个可启动的 USB 设备
- echarts自定义图例legend文字和样式
- 名图1.8智能隐藏功能_自动打包不脏手才是真智能,双11销冠,拓牛自动打包垃圾桶体验...
- python网络编程学习笔记(二)
- mysql workbench第二栏图标中英文意思
- 【小贴士】工作中的”闭包“与事件委托的”阻止冒泡“
- Lucene4:创建一个简单查询
- phpstorm 常用快捷键及自定义快捷键
- 苹果cms V10模板 仿挖片自适应电影模板
- 《谭浩强C语言程序设计》 · 素数 7-3
- android反编译修改教程,Android逆向反编译代码注入
- 关于CMOS摄像头的DVP接口的工作方式与一般使用方法
- DTCC2019 中国数据库技术大会见证实录(PPT 下载,来了!)
- 【实用性程序】弧微分计算圆周长
- 北京时间校准 服务器 显示器 标准,纯干货~北京时间校准显示器实用分享