今天是系列第五篇,主要讲一下上一篇遗留下来的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