Tengo una pregunta sobre cómo se trata el puntero "this" en un escenario de función anidada.
Digamos que inserto el siguiente código de muestra en una página web. Recibo un error cuando llamo a la función anidada "doSomeEffects ()". Revisé Firebug e indica que cuando estoy en esa función anidada, el puntero "this" en realidad apunta al objeto de "ventana" global, lo cual no esperaba. No debo estar entendiendo algo correctamente porque pensé que desde que declaré la función anidada dentro de una función del objeto, debería tener un alcance "local" en relación con la función (es decir, el puntero "this" se referiría al objeto en sí como cómo está en mi primera declaración "si").
Se agradecería cualquier sugerencia (sin juego de palabras).
var std_obj = {
  options : { rows: 0, cols: 0 },
  activeEffect : "none",
  displayMe : function() {
    // the 'this' pointer is referring to the std_obj
    if (this.activeEffect=="fade") { }
    var doSomeEffects = function() {
      // the 'this' pointer is referring to the window obj, why?
      if (this.activeEffect=="fade") { }
    }
    doSomeEffects();   
  }
};
std_obj.displayMe();
                
                    
                        javascript
                                function
                                nested
                                this
                                
                    
                    
                        JoJoeDad
fuente
                
                fuente

thisrefiere al objeto en el que se invoca la función.var self = this;y luego hacer referenciaselfen la función interna a través del cierre.doSomeEffectsno está asociado con ningún obj en particular, por lo quethisse supone que es la ventana, la madre de todos los elementos.Respuestas:
En JavaScript, el
thisobjeto se basa realmente en cómo realiza sus llamadas a funciones.En general, hay tres formas de configurar el
thisobjeto:someThing.someFunction(arg1, arg2, argN)someFunction.call(someThing, arg1, arg2, argN)someFunction.apply(someThing, [arg1, arg2, argN])En todos los ejemplos anteriores, el
thisobjeto serásomeThing. Llamar a una función sin un objeto principal principal generalmente le dará el objeto global que en la mayoría de los navegadores significa elwindowobjeto.fuente
this.doSomeEffects();según su respuesta, pero aún así no funciona. ¿Por qué?thisenthis.doSomeEffects()apunta astd_obj. Como se explicó en la respuesta anterior, si una función no tiene una referencia de objeto, entoncesthisdebe ser un objeto de ventana.Dado que esta parece ser una de las preguntas más votadas de su tipo, permítanme agregar, después de todos estos años, la solución ES6 usando funciones de flecha:
fuente
thisno es parte del alcance de cierre, se puede considerar como un parámetro adicional a la función que está vinculada al sitio de la llamada. Si el método no se llama como método, el objeto global se pasa comothis. En el navegador, el objeto global es idéntico awindow. Por ejemplo, considere la siguiente función,y el siguiente objeto,
Si llama a la función utilizando una sintaxis de método como,
entonces
thisestá obligado aobj.Si llama a someFunction () directamente, como,
luego
thisestá vinculado al objeto global, es decirwindow.La solución más común es capturar esto en el cierre, como,
fuente
Hay una diferencia entre las variables del recinto y "esto". "esto" en realidad está definido por el invocador de la función, mientras que las variables explícitas permanecen intactas dentro del bloque de declaración de función conocido como enclosure. Vea el ejemplo a continuación:
puedes probarlo aquí: http://jsfiddle.net/kSTBy/
Lo que está sucediendo en su función es "doSomeEffects ()", se llama explícitamente, esto significa contexto o el "esto" de la función es la ventana. si "doSomeEffects" era un método prototipo, por ejemplo this.doSomeEffects on say "myObject", myObject.doSomeEffects () haría que "this" fuera "myObject".
fuente
_this.name = myFirstObject this.name = mySecondObjectPara comprender esta pregunta, intente obtener el resultado del siguiente fragmento
El código anterior generará lo siguiente en la consola:
En la función externa, tanto this como self se refieren a myObject y, por lo tanto, ambos pueden hacer referencia y acceder correctamente a foo.
En la función interna, sin embargo, esto ya no se refiere a myObject. Como resultado, this.foo no está definido en la función interna, mientras que la referencia a la variable local self permanece dentro del alcance y es accesible allí. (Antes de ECMA 5, esto en la función interna se referiría al objeto de ventana global; mientras que, a partir de ECMA 5, esto en la función interna no estaría definido).
fuente
thisrefiere al objeto de ventana (en un entorno de navegador) o al objeto GLOBAL (en un entorno de node.js)thisya no se refiere a la ventanaComo explica Kyle, puede usar
calloapplypara especificarthisdentro de la función:Aquí está ese concepto aplicado a su código:
JsFiddle
fuente
También recibí una advertencia " Acceso de referencia potencialmente no válido a un campo de clase a través de este "
fuente
Como no se mencionó, mencionaré que usar
.bind()es una solución:Aquí hay un ejemplo más simple:
Es cierto que el uso de una función de flecha
=>parece más elegante y es fácil para el programador. Sin embargo, debe tenerse en cuenta que es probable que un alcance léxico requiera más trabajo en términos de procesamiento y memoria para configurar y mantener ese alcance léxico, en comparación con simplemente asociar una funciónthiscon un puntero vía.bind().Parte del beneficio de desarrollar clases en JS fue proporcionar un método para hacer
thispresente y disponible de manera más confiable, para alejarse de la programación funcional y los ámbitos léxicos y, por lo tanto, reducir la sobrecarga.De MDN
fuente