es7 - Javascript: ¿Cuál es la diferencia entre.call() y super()?
super js (2)
¿Cuál es la diferencia entre .call () y super ()? ¿Es super () solo una cosa es2015? ¿O tiene .call () más funcionalidad?
Imagino que relacionas call
y super
debido a un código como el siguiente:
function Foo() {
Bar.call(this)
}
class Foo extends Bar {
constructor() {
super()
}
}
En el caso anterior, ambos ejemplos hacen lo mismo (llamar al constructor de Bar
en el contexto de una nueva instancia de Foo
), pero a partir de allí el super
y la call
difieren mucho.
First off super
es una palabra clave, call
es un método del prototipo de Function
.
La palabra clave super
se puede usar para llamar al constructor de clase padre y a los métodos. Entonces, además de los ejemplos anteriores, super puede hacer esto:
class Bar {
constructor() {
//...
}
bang() {
console.log(''bang'')
}
}
class Foo extends Bar {
constructor() {
super()
//...
}
bang() {
// call parents method in context of `this`
super.bang()
//...
}
}
call
, por otro lado, es un método de la clase Function
que permite invocar una función con un valor explícito para this
variable. Considera la siguiente función.
function baz() { console.log(this.bar) }
baz() // -> "undefined"
baz.call({ bar: ''foo'' }) // -> "foo"
El ejemplo anterior es en realidad un poco más matizado. A menos que esté en modo estricto, this
será el objeto global
( global
, window
). En modo estricto, this
no está definido, y nuestra función baz
generará un error. Con la call
podemos establecer explícitamente this
, una característica muy poderosa.
super () llama al constructor de la clase que extened
class Foo extends Bar { constructor() { super(); // calls Bar''s constructor } }
llamada es una función genérica que puede usar con cualquier función
function a() { console.log(this); }; function b() { console.log(this); }; function c() { console.log(this}; }; a.call("hello"); b.call(123); c.call({});
Super sabe de qué clase heredaste y pasa automáticamente la correcta.
class Foo extends Bar { constructor() { super(); // calls Bar''s constructor } }
llamada requiere que seas explícito.
class Foo extends Bar { constructor() { Bar.call(this); // You had explicitly specify ''Bar'' // and explicitly pass ''this'' } }
super le permite invocar funciones en el padre implícitamente
class Bar { log() { console.log("bar-log"); } } class Foo extends Bar { log() { super.log(); } }
la llamada requiere que seas explícito
class Bar { log() { console.log("bar-log"); } } class Foo extends Bar { log() { Bar.prototype.log.call(this); // Explicitly reference bar''s log function // and explicitly specify ''this'' } }
Creo que podría argumentar que super
ofrece un subconjunto de la funcionalidad de call
. Algunos podrían llamarlo azúcar sintáctico, lo que significa que puedes usar la call
donde sea que puedas usar super
, super simplemente porque llama implícitamente cosas de la clase que extendiste / heredaste (técnicamente la siguiente en la cadena de prototipos?) Y porque pasa implícitamente this
para ti.