Понять роль метода конструктора и супер в классе ES6

внешний интерфейс JavaScript

Во-первых, ES6classОн относится к своего рода «синтаксическому сахару», поэтому он просто более элегантен и больше похож на объектно-ориентированное программирование, а его идеи согласуются с ES5.

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function() {
  return '(' + this.x + ',' + this.y + ')';
}

Эквивалентно

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ',' + this.y + ')';
  }
}

вconstructorМетод является конструктором класса и является методом по умолчаниюnewЭтот метод вызывается автоматически, когда команда создает экземпляр объекта. Класс должен иметьconstructorметод, если он не определен явно, по умолчаниюconsructorМетод будет добавлен по умолчанию. Поэтому, даже если вы не добавите конструктор, будет конструктор по умолчанию. в общемconstructorметод возвращает экземпляр объектаthis, но вы также можете указатьconstructorМетод возвращает совершенно новый объект, так что возвращаемый экземпляр объекта не является экземпляром класса.

Давайте хорошо проанализируемsuperРоль ключевых слов:

superЭто ключевое слово может использоваться либо как функция, либо как объект. В обоих случаях его использование совершенно бесполезно.

1. как функция использует

class A {}
class B extends A {
  constructor() {
    super();  // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
  }
}

Примечание: вconstructorдолжен быть вызванsuperметод, так как подклассы не имеют своих собственныхthisобъект, но наследует родительский классthisобъект, а затем обработать его, в то время какsuperОн представляет конструктор родительского класса.superХотя он представляет конструктор родительского класса A, он возвращает экземпляр подкласса B, то естьsuperВнутреннийthisотносится к B, поэтомуsuper()Это эквивалентно ````A.prototype.constructor.call(this, props)``.

class A {
  constructor() {
    console.log(new.target.name); // new.target 指向当前正在执行的函数
  }
}

class B extends A {
  constructor {
    super();
  }
}

new A(); // A
new B(); // B

Видно, что вsuper()При выполнении он указывает на конструктор подкласса B, а не на конструктор родительского класса A. То есть,super()Внутреннийthisуказывает на Б.

2. Использовать как объект

В обычных методах он указывает на объект-прототип родительского класса, в статических — на родительский класс.

class A {
  c() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.c()); // 2
  }
}

let b = new B();

В приведенном выше коде в подклассе Bsuper.c(), этоsuperиспользуется как предмет. В настоящее время,superОбычными методами, указывая наA.prototype,такsuper.c()эквивалентноA.prototype.c().

пройти черезsuperПри вызове метода родительского классаsuperбудет связывать подклассthis.

class A {
  constructor {
    this.x = 1;
  }
  s() {
    console.log(this.x);
  }
}

class B extends A {
  constructor {
    super();
    this.x = 2;
  }
  m() {
    super.s();
  }
}

let b = new B();
b.m(); // 2

В приведенном выше кодеsuper.s()Хотя звонокA.prototytpe.s(),ноA.prototytpe.s()будет связывать подкласс Bthis, В результате на выходе будет 2 вместо 1. Что, собственно, и выполняетсяsuper.s.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, но нетxметод, поэтому возвращает undefined.

Обратите внимание, что использованиеsuperПри его использовании необходимо явно указать, используется ли он как функция или как объект, иначе будет сообщено об ошибке.

class A {}
class B extends A {
  constructor() {
    super();
    console.log(super); // 报错
  }
}

В приведенном выше кодеconsole.log(super);принадлежащийsuper, невозможно увидеть, используется ли он как функция или как объект, поэтому движок JavaScript сообщит об ошибке при разборе кода. Это если можно наглядно показатьsuperтип данных, об ошибке не будет сообщено.

Наконец, поскольку объекты всегда наследуются от других объектов, в любом объекте используйтеsuperключевые слова.

Заключение:
В конце концов, класс ES6 — это «синтаксический сахар», поэтому, пока вы понимаете концепцию объектов и объектно-ориентированных идей в JavaScript, понять классы несложно.