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
this
refiere al objeto en el que se invoca la función.var self = this;
y luego hacer referenciaself
en la función interna a través del cierre.doSomeEffects
no está asociado con ningún obj en particular, por lo quethis
se supone que es la ventana, la madre de todos los elementos.Respuestas:
En JavaScript, el
this
objeto se basa realmente en cómo realiza sus llamadas a funciones.En general, hay tres formas de configurar el
this
objeto:someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
En todos los ejemplos anteriores, el
this
objeto 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 elwindow
objeto.fuente
this.doSomeEffects();
según su respuesta, pero aún así no funciona. ¿Por qué?this
enthis.doSomeEffects()
apunta astd_obj
. Como se explicó en la respuesta anterior, si una función no tiene una referencia de objeto, entoncesthis
debe 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
this
no 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
this
está obligado aobj
.Si llama a someFunction () directamente, como,
luego
this
está 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 = mySecondObject
Para 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
this
refiere al objeto de ventana (en un entorno de navegador) o al objeto GLOBAL (en un entorno de node.js)this
ya no se refiere a la ventanaComo explica Kyle, puede usar
call
oapply
para especificarthis
dentro 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ónthis
con un puntero vía.bind()
.Parte del beneficio de desarrollar clases en JS fue proporcionar un método para hacer
this
presente 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