¿Cómo paso el contexto a una función?


213

Pensé que esto sería algo que podría fácilmente googlear, pero tal vez no estoy haciendo la pregunta correcta ...

¿Cómo configuro todo lo que se refiere a "esto" en una determinada función de JavaScript?

por ejemplo, como con la mayoría de las funciones de jQuery como:

$(selector).each(function() {
   //$(this) gives me access to whatever selector we're on
});

¿Cómo escribo / llamo a mis propias funciones independientes que tienen una referencia apropiada "this" cuando se llama? Yo uso jQuery, así que si hay una forma específica de jQuery de hacerlo, sería ideal.



Sé que esta es una vieja pregunta, pero para otros que aterrizan aquí, ver jQuery$.proxy
RyBolt

Respuestas:


302

Los javascripts .call()y los .apply()métodos le permiten establecer el contexto para una función.

var myfunc = function(){
    alert(this.name);
};

var obj_a = {
    name:  "FOO"
};

var obj_b = {
    name:  "BAR!!"
};

Ahora puedes llamar:

myfunc.call(obj_a);

Lo cual alertaría FOO. Al revés, pasar obj_balertaría BAR!!. La diferencia entre .call()y .apply()es que .call()toma una lista separada por comas si está pasando argumentos a su función y .apply()necesita una matriz.

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

Por lo tanto, puede escribir fácilmente una función hookutilizando el apply()método Por ejemplo, queremos agregar una función al .css()método jQuerys . Podemos almacenar la referencia de función original, sobrescribir la función con código personalizado y llamar a la función almacenada.

var _css = $.fn.css;
$.fn.css = function(){
   alert('hooked!');
   _css.apply(this, arguments);
};

Dado que el argumentsobjeto mágico es una matriz como objeto, simplemente podemos pasarlo apply(). De esa forma, garantizamos que todos los parámetros pasan a la función original.


44
Solo un dato divertido: si necesita llamar a la función repetidamente en referencia a obj_a, por ejemplo, puede crear una copia var boud_myfunc = myfunc.bind(obj_a)y simplemente llamar bound_myfunc()según sea necesario.
wbadart

44

Usofunction.call :

var f = function () { console.log(this); }
f.call(that, arg1, arg2, etc);

¿Dónde thatestá el objeto que desea thisen la función?


1
functiones una palabra clave reservada; considere actualizar su respuesta para incluir una función con nombre ya function.call(...)que no es JavaScript válido.
Daniel Allen

1
@DanielAllen: Sin la definición del nombre de la función de muestra que proporcionaría, el código aún arrojará un error JS. Pero actualicé el nombre de la función de muestra.
palswim

16

jQuery utiliza un .call(...)método para asignar el nodo actual al thisinterior de la función que pasa como parámetro.

EDITAR:

No tenga miedo de mirar dentro del código de jQuery cuando tenga dudas, todo está en JavaScript claro y bien documentado.

es decir: la respuesta a esta pregunta está alrededor de la línea 574,
callback.call( object[ name ], name, object[ name ] ) === false


12

Puede usar la función de vinculación para establecer el contexto thisdentro de una función.

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"

12

Otro ejemplo básico:

No funciona:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
};
img.src = reader.result;

Trabajando:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
}.bind(this);
img.src = reader.result;

Básicamente: simplemente agregue .bind (this) a su función


Esta debería ser la respuesta aceptada. Sintaxis mucho más fácil, mucho más fácil en la mente ... buen trabajo Joery
nenea
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.