предисловие
Эта статья написана после прочтения учебника по es6 учителя Руана, см.super
Когда дело доходит до ключевых слов, я считаю необходимым обобщить и разобраться, исходный текст все еще является ссылкойНачало работы с ECMAScript 6.
текст
super
Это ключевое слово может использоваться и как функция, и как объект.
1. Использовать как функцию
super
Когда он вызывается как функция, он представляет конструктор родительского класса.ES6
Требует, чтобы конструктор подкласса был выполнен один разsuper
функция.
то есть как函数
При использовании кода ниже固定使用套路
:
class A {
constrctor(){
}
}
class B extends A {
constructor() {
super();
}
}
Кого представляет super() в приведенном выше коде? ?
ПодклассB
в конструктореsuper()
,представлятьB
вызвать родительский классA
Конструктор выполняется.
Примечание⚠️: хотяsuper()
представленный родительским классомA
конструктор, но возвращает подклассB
экземпляр, то естьsuper()
Внутреннее this относится к B, поэтомуsuper()
здесь эквивалентноA.prototype.constructor.call(this)
.
Большой каштан в доказательство моего тезиса:
class A {
constrctor(){
console.log(new.target.name)
}
}
class B extends A{
constructor(){
super()
}
}
new A() // A
new B() // B
В этом парном кодеnew.target
Указывает на текущую выполняемую функцию.
Мягко говоря:
new
это команда для экземпляра объекта, сгенерированного из конструктора. ES6 этоnew
команда вводитnew.target
Атрибут, который обычно используется в конструкторах и возвращает конструктор, над которым действует новая команда.
Видно, что вsuper()
При выполнении он указывает на подклассB
конструктор, а не родительский классA
конструктор. которыйsuper()
Внутреннее это относится кB
.
Еще один момент, который следует отметить⚠️:
Как функцию Super() можно использовать только в конструкторе подклава, а использовать его в других местах.
// 错误写法
class A {}
class B extends A {
m() {
super(); // 报错
}
}
В заключение:
При использовании super в качестве функции необходимо обратить внимание на следующие три момента:
- Конструктор подкласса должен быть выполнен один раз
super
функция.
// 再次重申,这是固定写法
class A {
constructor() {}
}
class B extends A {
constructor() {
super();// 这里表示 A.constructor()
}
}
- в конструкторе подкласса
super()
Это означает, что подкласс вызывает конструктор родительского класса для выполнения, в это времяsuper()
это в父类.constructor
серединаthis
, который относится к подклассу.
3.super() можно использовать только в конструкторе подкласса, а в других местах будет сообщено об ошибке.
2. Когда super — это объект
super
В качестве объекта в обычном методе он указывает на объект-прототип родительского класса, а в статическом методе — на родительский класс.
2.1 super используется как объект в обычных методах
Над кодом:
class A {
p(){
return 2
}
}
class B extends A {
constrctor(){
super();
console.log(super.p());//2
}
}
let b = new B();
Мы обнаружили, что в подклассеB
серединаsuper.p()
Результат выполнения2
. Мы предполагаем здесьsupsuper.p === A.prototype.p
, убедитесь, что результатtrue
:
class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p===A.prototype.p); // true
}
}
let b = new B();
То есть в это времяsuper
В обычном методе, указывая наA.prototype
то есть в подклассеsuper
Указатель на объект-прототип родительского класса.
⚠️Примечание 1.: из-заsuper
Он указывает на объект-прототип родительского класса, поэтому методы или свойства, определенные в экземпляре родительского класса, не могут быть переданы.super
называется.
class A {
constructor() {
this.s = 3;
}
}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2 这里可以获取到父类原型上的x属性
}
get m(){
return super.s
}
}
let b = new B();
console.log(b.m)// undefined 不能获取到定义在父类实例上的s属性
Через приведенный выше код мы находим:
ПодклассB
в состоянии пройтиsuper
Получить свойства, определенные в прототипе родительского класса, но определенные в родительском классеA
Не удалось получить свойства экземпляра .
Заметка 2⚠️:это указывает на
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();// 这里等同于 A.proptotype.print()
}
}
let b = new B();
b.m() // 2
В приведенном выше кодеsuper.print()
Хотя звонитA.prototype.print()
,ноA.prototype.print()
Внутреннее this указывает на экземпляр подкласса B, что приводит к 2 вместо 1. То есть то, что на самом деле выполняется,super.print.call(this)
.
Заметка 3⚠️:пройти черезsuper
выполнить задание
из-заthis
указывает на экземпляр подкласса, поэтому, если вы передадитеsuper
Присвойте значение свойству, затемsuper
то естьthis
, назначенное свойство становится свойством экземпляра подкласса.
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;// 此时的 super 就是 b
console.log(super.x); // undefined 等用于是 A.prototype.x
console.log(this.x); // 3
}
}
let b = new B();
Через эти два куска кода мы нашли проблему, когда я прохожуsuper
Когда принимается значение, берется свойство прототипа родительского класса, но когда я передаюsuper
при назначенииsuper
Указывает на экземпляр подкласса.
В заключение:
Из трех каштанов выше,super
При применении в обычном методе в качестве объекта:
- в подклассе
super
Он указывает на объект-прототип родительского класса, поэтому методы или свойства, определенные в экземпляре родительского класса, не могут быть переданы.super
называется. - Передайте нормальный метод подкласса
super
При вызове метода родительского класса this внутри метода указывает на текущий экземпляр подкласса. - Назначьте свойство свойству через super, затем super is this, и назначенное свойство станет свойством экземпляра подкласса.
2.2 super применяется как объект в статическом методе
если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 指的是父类,Parent
super.myMethod(msg);
}
myMethod(msg) {
// 普通函数 此时 super 是指 Parent.prototype
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
В приведенном выше коде super указывает на родительский класс в статическом методе и указывает на объект-прототип родительского класса в обычном методе.
Примечание 1 ⚠️
в статическом методе подкласса черезsuper
При вызове метода родительского класса метод внутри методаthis
Указывает на текущий подкласс, а не на экземпляр подкласса.
class A {
constructor() {
this.x = 1;
}
static print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
static m() {
super.print();// A.print 中的this指向当前的子类
}
}
B.x = 3;
B.m() // 3
В приведенном выше коде статический методB.m
в,super.print
Статический метод, указывающий на родительский класс. в этом методеthis
указывает наB
, вместоB
пример.
В заключение:
в статическом методе подкласса черезsuper
При вызове метода родительского класса метод внутри методаthis
Указывает на текущий подкласс, а не на экземпляр подкласса.
во всяком случае
-
super
как функция,super()
Представляет конструктор родительского класса внутриthis
является экземпляром класса. -
super
как объект, в обычном методеsuper.
Синтаксис указывает на объект-прототип родительского класса, который используется в статических методах.super.
Синтаксис заключается в том, чтобы перейти к статическому методу родительского класса, чтобы найти его. Что касаетсяthis
Укажите на вопрос, помните одну вещь:Если перед методом добавитьstatic
ключевое слово, оно означает, что метод не будет унаследован экземпляром, а будет вызываться напрямую через класс, поэтому в статическом методеthis
будет ссылаться только на классы, а не на экземпляры.