推荐答案
super
关键字在 ES6 中主要有两个作用,且都与类的继承相关:
在子类的构造函数中使用
super()
:super()
用于调用父类的构造函数。必须在子类的构造函数中使用this
关键字之前调用super()
。这是因为this
关键字需要在父类构造函数执行后才能正确初始化。super()
可以接受参数,这些参数会传递给父类的构造函数。
在子类的方法中使用
super.methodName()
:super.methodName()
用于调用父类中定义的方法。这允许子类在继承父类方法的基础上进行扩展或修改。- 可以用来访问父类中被子类方法覆盖的方法。
本题详细解读
继承与 super
的必要性
在 ES6 中,通过 class
关键字可以定义类,并且可以使用 extends
关键字实现类的继承。当一个子类继承父类时,子类会继承父类的属性和方法。但是,子类也需要有自己的构造逻辑,以及可能需要修改或扩展父类的方法。这就是 super
关键字存在的意义。
super()
的作用和用法
当子类需要自己的构造逻辑时,我们必须在子类的构造函数中使用 super()
来调用父类的构造函数。super()
的主要作用是:
- 初始化
this
: 在 ES6 的类继承中,子类构造函数必须先执行父类构造函数,这样才能正确地初始化this
对象。如果没有调用super()
,则尝试使用this
会抛出错误。 - 继承父类属性:
super()
会执行父类的构造函数,这意味着子类可以继承父类在构造函数中初始化的属性。
示例:
-- -------------------- ---- ------- ----- ------ - ----------------- - --------- - ----- - ------- - -------------------- ------ -------- - - ----- --- ------- ------ - ----------------- ------ - ------------ -- --------- ---------- - ------ - ------ - --------------------- - - ----- ----- - --- ------------ ------------ ------------------------ -- --- ----- ------------------------- -- --- -------- -------------- -- --- ------- ------ ----- ------------- -- --- -----
在上面的示例中,Dog
继承了 Animal
。 Dog
类的构造函数中使用了 super(name)
来调用父类 Animal
的构造函数,并传递了 name
参数。这确保了 Dog
实例也具有 name
属性。
super.methodName()
的作用和用法
当子类需要调用父类的方法时,可以使用 super.methodName()
。这通常发生在以下两种情况:
- 扩展父类方法: 子类可以在调用父类方法的基础上添加额外的逻辑。
- 覆盖父类方法: 子类可以完全覆盖父类方法,如果仍然需要使用父类的方法,可以使用
super.methodName()
来调用。
示例:
-- -------------------- ---- ------- ----- ------ - ------- - -------------------- ------ -------- - - ----- --- ------- ------ - ------- - -------------- -- ----- ----- -- --------------------- -- ------- - - ----- ----- - --- ------ -------------- -- --- ------- ------ ----- -- -----
在这个示例中,Dog
类覆盖了父类 Animal
的 speak
方法。但是,在 Dog
的 speak
方法内部,使用了 super.speak()
来调用父类的 speak
方法,然后又添加了 console.log('Woof!');
语句,从而扩展了 speak
方法的功能。
注意事项
- 必须在
this
之前调用super()
: 在子类构造函数中,必须在访问this
之前调用super()
。否则,会抛出错误。 - 只在构造函数和方法中使用:
super
只能在子类的构造函数和方法中使用。在其他地方使用super
会导致错误。 super
的上下文:super
的上下文始终是当前子类的实例。