En un archivo javascript, cuando declaro una función usando la palabra clave function, puedo colocar mi función después de mi función de llamada, algo como

// test.js
function myCaller() {
   foo('hello world');    // this works!
   this.foo('hello world');  // this works!
}
function foo(text) {
   console.log('foo called!', text);
}
myCaller()

Pero si convertí el foo en una función de flecha y lo coloqué en la misma posición, entonces en la función myCaller, dijo que foo no está definido, tampoco funcionará si use la palabra clave this para ubicar la función foo, que supongo que this se refiere al nivel global / de documento

// test.js
function myCaller() {
   foo('hello world');    // es-lint warning: 'foo' was used before it was defined
   this.foo('hello world');  // compilation error: foo is not defined
}
const foo = (text) => {
   console.log('foo called!', text);
}
myCaller();

- Me equivoqué, pensé que el segundo enfoque sin usar this no funciona debido al error de compilación de JavaScript de not defined, pero en realidad fue mi error de eslint - 'foo' was used before it was defined, ¿significa que es no recomiendo hacerlo de esta manera?

¿Por qué es eso y significa que tenemos que declarar la función de flecha siempre por encima de la función caller? ¿Hay alguna forma alternativa de resolver eso?

const foo = (text) => {
   console.log('foo called!', text);
}
// test.js
function myCaller() {
   foo('hello world');    // this works! no es-lint warning now
   this.foo('hello world');  // no compilation error but there is a run-time error : 'this.foo is not a function'
}

myCaller();

Además, descubrí que cuando declaro la función de flecha dentro de una clase de JavaScript, funcionaría con la palabra clave this solo con la función de llamada como función de flecha también, si la función de llamada es con la palabra clave function, esto no trabaja...

// myTest.js
class myTest {
   myCaller() {
      foo('hello world');    // compilation error: foo is undefined
   }
   myCaller2 = () => {
     this.foo('hello world'); //this works!
   }
   foo = (text) => {
      console.log('foo called!', text);
   }
}
new myTest().myCaller();
new myTest().myCaller2();
0
KevDing 23 ago. 2020 a las 08:46

1 respuesta

La mejor respuesta

Cualquier variable (excepto las variables let y const) que declare o funciones que defina en contexto global (digamos, directamente en test.js) se adjuntará al objeto Window. Entonces, cuando escribes,

// test.js
function myCaller() {
   foo('hello world');    // this works!
   this.foo('hello world');  // this works!
}
function foo(text) {
   console.log('foo called!', text);
}
myCaller()

Tanto myCaller como foo se adjuntan al objeto de ventana como propiedades. Ahora puede referirse a ellos directamente como foo() (esto está implícito aquí) o this.foo() o incluso window.foo(). Dado que js usa izado, estas variables o funciones se adjuntan primero al contexto y luego comienzan a ejecutarse.

Pero const y let no están adjuntos al objeto Ventana (de lo contrario, serían accesibles en todas partes, comportándose exactamente como var). Entonces cuando escribes

// test.js
function myCaller() {
   foo('hello world');
   this.foo('hello world');
}
const foo = (text) => {
   console.log('foo called!', text);
}
myCaller();

El motor Javascript escanea todo el script para ver si hay variables o funciones definidas. En esta fase de elevación, si encuentra un const o let, les asigna memoria pero no los hará parte del objeto Window. Entonces, cuando se refiere a this en contexto global, se refiere al objeto de ventana y foo no es una propiedad del objeto de ventana. Por eso, incluso si coloca const foo encima de la definición de myCaller, no funcionará.

En el caso de la clase, si intenta llamar a foo() directamente sin hacer referencia a esto, intenta acceder a ella desde los contextos adjuntos, donde no está definido en su ejemplo. Entonces arroja error. Si define otro foo() fuera de la clase con var o directamente como foo = (text) => ..., funcionará.

(Es posible que this no siempre se refiera al contexto global. Las funciones y clases pueden tener su propio contexto personalizado, y this se referiría a ese contexto. Pero cuando las funciones o clases no definen ningún contexto personalizado , el contexto global será al que se referiría la palabra clave this. this no está definido para funciones y clases de forma predeterminada en modo estricto. Hay varias advertencias que deben tenerse en cuenta).

1
chethan7 23 ago. 2020 a las 08:33