www whatwg what spec language español 3wc javascript

whatwg - setTimeout y "this" en JavaScript



whatwg español (5)

Me sale un error que dice que method2 no está definido

Sí, cuando this.method de su propietario y pasas la función solo a setTimeout , pierdes la asociación que establece this , por lo que this en method() es igual a la window objeto global.

Consulte esta respuesta para obtener una explicación de la sorprendente manera en que this realmente funciona en JavaScript.

Tengo un método que usa la función setTimeout y realiza una llamada a otro método. En el método de carga inicial 2 funciona bien. Sin embargo, después del tiempo de espera, aparece un error que dice que el method2 no está definido. ¿Qué estoy haciendo mal aquí?

ex:

test.prototype.method = function() { //method2 returns image based on the id passed this.method2(''useSomeElement'').src = "http://www.some.url"; timeDelay = window.setTimeout(this.method, 5000); }; test.prototype.method2 = function(name) { for (var i = 0; i < document.images.length; i++) { if (document.images[i].id.indexOf(name) > 1) { return document.images[i]; } } };


El problema es que setTimeout() hace que javascript use el alcance global. Básicamente, estás llamando a la clase method() , pero no a partir de this . En su lugar, solo le está diciendo a setTimeout que use el method función, sin un alcance particular.

Para solucionarlo, puede ajustar la llamada a la función en otra llamada de función que haga referencia a las variables correctas. Se verá algo como esto:

test.protoype.method = function() { var that = this; //method2 returns image based on the id passed this.method2(''useSomeElement'').src = "http://www.some.url"; var callMethod = function() { that.method(); } timeDelay = window.setTimeout(callMethod, 5000); };

that puede ser porque callMethod() encuentra dentro del alcance del método.

Este problema se vuelve más complejo cuando necesita pasar parámetros al método setTimeout , ya que IE no admite más de dos parámetros para setTimeout . En ese caso, deberás leer sobre closures .

Además, como nota al margen, te estás preparando para un ciclo infinito, ya que el method() siempre llama a method() .


Una opción más elegante es agregar .bind(this) al final de su función. P.ej:

setTimeout(function() { this.foo(); }.bind(this), 1000); // ^^^^^^^^^^^ <- fix context

Entonces, la respuesta a la pregunta del OP podría ser:

test.prototype.method = function() { //method2 returns image based on the id passed this.method2(''useSomeElement'').src = "http://www.some.url"; timeDelay = window.setTimeout(this.method.bind(this), 5000); // ^^^^^^^^^^^ <- fix context };


el this que setTimeOut en setTimeOut está setTimeOut por sí mismo. Crea una var "foo = this;" dentro de su función t est.prototype.method y use foo lugar.


en es6 puedes hacerlo así

window.setTimeout(() => { this.foo(); }, 1000);