En primer lugar, ES6 class
es una especie de "azúcar sintáctico", por lo que está escrito de manera más elegante, más como programación orientada a objetos, y su idea es consistente con ES5.
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function() {
return '(' + this.x + ',' + this.y + ')';
}
Equivalente a
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ',' + this.y + ')';
}
}
El constructor
método es el constructor de la clase, que es un método predeterminado new
y se llama automáticamente cuando se crea una instancia de objeto mediante el comando. Una clase debe tener constructor
un método; si no se define explícitamente, consructor
se agregará un método predeterminado de forma predeterminada. Entonces, incluso si no agrega un constructor, habrá un constructor predeterminado. El método general constructor
devuelve un objeto de instancia this
, pero también se puede especificar constructor
que el método devuelva un objeto nuevo, de modo que el objeto de instancia devuelto no sea una instancia de esta clase.
Echemos un vistazo más de cerca al super
papel de las palabras clave:
super
Esta palabra clave se puede utilizar como función o como objeto. En ambos casos, su uso es completamente inútil.
1. Usar como función
class A {}
class B extends A {
constructor() {
super(); // ES6 要求,子类的构造函数必须执行一次 super 函数,否则会报错。
}
}
Nota: El método constructor
debe llamarse super
porque la subclase no tiene su propio this
objeto, pero hereda el objeto de la clase principal this
y luego lo procesa y super
representa el constructor de la clase principal. super
Aunque representa el constructor de la clase principal A, devuelve una instancia de la subclase B, es decir, lo super
interno this
se refiere a B, por lo que super()
aquí es equivalente a ```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
Se puede ver que cuando super()
se ejecuta, apunta al constructor de la subclase B, no al constructor de la clase principal A. Es decir, super()
el interno this
apunta a B.
2. Úselo como objeto
En métodos ordinarios, apunta al objeto prototipo de la clase padre; en métodos estáticos, apunta a la clase padre.
class A {
c() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.c()); // 2
}
}
let b = new B();
En el código anterior, en la subclase B super.c()
, se super
utiliza como objeto. En este momento, super
en el método ordinario, apuntar A.prototype
, por lo que super.c()
es equivalente a A.prototype.c()
.
Al super
llamar al método de la clase principal, super
se vinculará la subclase 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
En el código anterior, super.s()
aunque se llama A.prototytpe.s()
, A.prototytpe.s()
vinculará la subclase B this
, lo que dará como resultado un resultado de 2 en lugar de 1. Es decir, lo que realmente se ejecuta es super.s.call(this)
.
Debido a la vinculación de subclases this
, si super
asigna un valor a una determinada propiedad, super
la this
propiedad asignada se convertirá en propiedad de la instancia de la subclase.
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();
En el código anterior, super.x
asignar un valor de 3 equivale a asignar this.x
un valor de 3 a . Y al leer super.x
, se llama A.prototype.x
, pero no hay ningún x
método, por lo que se devuelve indefinido.
Tenga en cuenta que super
cuando lo use, debe especificar explícitamente si desea usarlo como una función o como un objeto; de lo contrario, se informará un error.
class A {}
class B extends A {
constructor() {
super();
console.log(super); // 报错
}
}
console.log(super);
En el código anterior, super
es imposible saber si se usa como función o como objeto, por lo que el motor JavaScript informará un error al analizar el código. Es decir, si se puede indicar claramente el tipo de datos super
, no se reportará ningún error.
Finalmente, dado que los objetos siempre heredan de otros objetos, puedes usar la palabra clave en cualquier objeto super
.
Conclusión:
Después de todo, la clase ES6 es un "azúcar gramatical", por lo que siempre que comprenda el concepto de objetos y el pensamiento orientado a objetos en JavaScript, la clase no es difícil de entender.