Usar `super` dentro de una función de flecha dentro de una función de flecha dentro de un método
Estoy tratando de averiguar si veo algún comportamiento en el Nodo v4.1.1 (V8 v4.5.103.33) con respecto asuper
y las funciones de flecha escomportamiento especificado, y si es así (o de hecho, si no),donde es en elespecificación que dice que debería (o no debería) funcionar en los diversos casos que tengo.
En resumen: usosuper
en una función de flecha (inner
) dentro de otra función de flecha (outer
) dentro de un método funcionaa no ser que outer
tiene argumentos o variablesinner
referencias, incluso siinner
referencias argumentos o variables demethod
. quiero saberlo que dice la especificación sobre eso: ¿Debería funcionar todo el tiempo, incluso cuando V8 falla? ¿Ninguna de las veces? ¿Solo en los casos específicos donde V8 lo está dejando funcionar actualmente y no donde no lo está?
Aquí hay un MCVE:
"use strict";
class Parent {
show(msg) {
console.log(`Parent#show: ${msg}`);
}
}
class Child extends Parent {
method(arg) {
let outer = (x) => {
console.log(`outer: x = ${x}`);
let inner = () => {
super.show(`arg = ${arg}, x = ${x}`);
};
inner();
};
outer(42);
}
}
new Child().method("arg");
Eso falla con:
$ node test.js /path/test.js:13 super.show(`arg = ${arg}, x = ${x}`); ^^^^^ SyntaxError: 'super' keyword unexpected here at outer (/path/test.js:16:13) at Child.method (/path/test.js:18:9) at Object. (/path/test.js:22:13) at Module._compile (module.js:434:26) at Object.Module._extensions..js (module.js:452:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12) at Function.Module.runMain (module.js:475:10) at startup (node.js:117:18) at node.js:951:3
Si elimina la referencia ax
eso es eninner
:
let inner = () => {
super.show(`arg = ${arg}`); // <== removed x from this
};
esotrabajos y salidas:
outer: x = 42 Parent#show: arg = arg
Para demostrarme a mí mismo que el caso "funciona" no era que las funciones se estaban optimizando, las devolví fuera del método y las llamé. Aquí está ese caso un poco más complejo (tenga en cuenta los comentarios); Esta versióntrabajos:
"use strict";
class Parent2 {
show(msg) {
console.log(`Parent2#show: ${msg}`);
}
}
class Child2 extends Parent2 {
method(arg) {
let flag = Math.random() < 0.5;
console.log(`method called with ${arg}, flag is ${flag}`);
let x = "A"; // **A**
let outer2 = (/*x*/) => { // **B**
//let x = "C"; // **C**
let inner2 = () => {
super.show(`${x}: ${arg} (${flag})`);
};
return inner2;
};
return outer2;
}
}
let o = new Child2().method("arg");
console.log(`type of outer2: ${typeof o}`);
let i = o();
console.log(`type of inner2: ${typeof i}`);
i("B");
Salida:
method called with arg, flag is false type of outer2: function type of inner2: function Parent2#show: A: arg (false)
Pero si comentamos la línea etiquetadaA
y descomentar tampocoB
oC
, falla como lo hace el MCVE.
Más notas:
Debo enfatizar que necesitas tener las funciones de flechaanidado. outer
no tiene problemas para accedersuper
. No quiero saturar la pregunta con otro bloque de código grande, pero si agregasuper.show(`outer: arg = ${arg}, x = ${x}`);
en la cima deouter
Funciona bien.
Como puedes ver,inner
usa tanto un argumento como una variable demethod
(bueno, el MCVE solo usa un argumento), y eso está bien, pero tan pronto comoinner
intenta usar un argumento o variable deouter
, las cosas explotan.
Babel y Traceur están perfectamente felices de transpilar el caso de que V8 no se ejecutará (aquí yaquí), pero eso podría ser simplemente que están haciendo algo mal que V8 hace bien (o, por supuesto, viceversa).
No se relaciona con cadenas de plantillas; la versión anterior a MCVE de esto no los usaba (y sí usaba promesas, que es cómo terminamos con flechas dentro de flechas).
Solo para enfatizar, la pregunta escual es el comportamiento especificado aquí ydonde en la especificación se especifica.
Mi instinto me dice que esto es solo un error V8: son los primeros días para estas cosas, después de todo, es bastante tonto. Pero de cualquier manera, solo estoy tratando de averiguar cuál es el comportamientodebiera ser, lo que dice la especificación. He tratado de seguir sus diversas y diversas secciones hablando desuper
y "objetos base" y tal, y francamente no lo estoy entendiendo.