今天是系列第五篇,主要讲一下上一篇遗留下来的es6继承的具体使用问题。因为在es6继承中用到了一些语法糖,书写方式跟es5的继承写法上有很大的不同,所以专门把它拎出来讲。言归正传,下面我将其对应的一些关键字的用法进行阐述,并配合一些例子来解释。
constructor
- 定义:是类的构造函数。
- 用法:在使用 new 实例化对象的时候,会自动调用这个方法。
- 注意:一个类必须有 constructor 方法,如果没有显式定义,会默认添加 consructor 方法。所以即使你没有添加构造函数,也是会有一个默认的构造函数的。一般 constructor 方法返回当前实例对象 this ,但是也可以指定 constructor 方法返回一个全新的对象,让返回的实例对象不是该类的实例。
举个例子:
class Demo{
say(){
console.log('我在创建一个例子')
}
}
const demo = new Demo()
console.log(demo) // demo {__proto__:{constructor:###, say:function(){###}}}
demo.say() // 我在创建一个例子
在上面这个例子中创建了一个Demo类,并且没有创建constructor方法。打印实例化对象demo,我们可以看到在该对象的__proto__方法下有constructor属性和say方法,所以可以证明上面的结论:在没有显式定义constructor方法的时候,会默认添加一个返回this(指向实例)的构造函数。
super
- 定义:它是一个用于访问父类对象上函数的关键字。
-
用法:可以当做函数使用,也可以当做对象使用。即存在super(…)或者super.xxx(…)这两种使用方式。单独调用super会报错
-
作为函数使用时(看例子):
- 如果想让实例对象使用到构造函数中的属性,在 constructor 中必须调用 super 方法,因为子类没有自己的this对象,而是继承父类的this对象,而super就代表了父类的构造函数。super虽然代表了父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类。
- 如果只是想调用该类的原型方法时,在 constructor中就可以不用调super方法。只需要再constructor方法中手动返回一个值即可
-
// 没有调用super的情况
class Demo{
construcor(){
return 1
}
say(){
console.log('我创建了一个demo')
}
}
const demo = new Demo()
demo.say() // 我创建了一个demo
- 当做对象使用:
- 在普通方法中,指向父类的原型对象;所以在子类的方法中super.print();指向的是父类原型上的方法。
- 在静态方法中,指向父类。但是因为super的两种用法,所以es6规定在使用必须要明确使用方式,像单独console.log(super) 就会报错。
```
// demo1,普通方法
class A {
constructor() {
this.x = 1
}
say(){
console.log('说话')
}
}
class B extends A {
constructor() {
super();
super.x = 3;
// super指向父类的原型对象,原型对象里没有父类实构造函数的属性
console.log(super.x); // undefined
// say是在原型链上父类的原型方法,可以获取到
console.log(super.say === this.say); // true
console.log(this.x); // 3
}
}
let b = new B();
// demo2,静态方法指向父类
class A {
static say() {
console.log('说话')
}
}
class B extends A {
constructor() {
super();
}
static action(){
super.say()
}
}
B.action() // 说话
```
- 注意:super的使用方式只有super()和super.###()这两种。这一点比较特殊,如果直接单独使用super,如console.log(super)时,就会抛出错误。
static
- 创建静态方法的关键字。类相当于实例的原型, 所有在类中定义的方法, 都会被实例继承。 如果在一个方法前, 加上static关键字, 就表示该方法不会被实例继承, 而是直接通过类来调用。静态方法调用直接
在类上进行,而在类的实例上不可被调用。静态方法通常用于创建 实用/工具 函数。
new.target
- 定义:检测函数或构造方法是否是通过new运算符被调用的。
-
new.target使用的场景
- 通过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。
- 在普通的函数调用中,new.target的值是undefined。
看栗子:
class A {
constructor(name, age){
this.name = name
this.age = age
console.log(new.target === A) // true
}
say() {
// new.target === undefined
console.log(`我叫${this.name},今年${this.age}岁,看看new.target的值:${new.target}`)
}
}
const a = new A('小李', 20)
a.say()
总结
-
constructor
- 是类的构造函数。
- 在使用 new 实例化对象的时候,会自动调用这个方法。
-
super
- 是一个用于访问父类对象上函数的关键字。
-
可以当做函数使用,也可以当做对象使用。即存在super(…)或者super.xxx(…)这两种使用方式,单独调用super会报错。但是两种使用super方法的指向是不同的,这点需要特别注意一下。
- 在子类constructor调用super()时,其内部this指向子类
-
作为对象使用:
- 在普通方法中,指向父类的原型对象
- 在静态方法中,指向父类
-
static
- 创建静态方法的关键字
-
new.target
- 检测函数或构造方法是否是通过new运算符被调用的。
- 在构造函数中调用,指向构造方法或者函数的应用;作为普通函数返回undefiend
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。