ti-enxame.com

Como eu passo o contexto para uma função?

Eu pensei que isso seria algo que eu poderia facilmente google, mas talvez eu não esteja fazendo a pergunta certa ...

Como faço para definir o que "isto" se refere em uma determinada função javascript?

por exemplo, como com a maioria das funções do jQuery, como:

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

Como faço para escrever/chamar minhas próprias funções autônomas que têm uma referência "this" apropriada quando chamadas? Eu uso o jQuery, então, se há uma maneira específica de fazer isso, seria ideal.

187
user126715

Os métodos Javascripts .call() e .apply() permitem que você defina o contexto para uma função.

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

var obj_a = {
    name:  "FOO"
};

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

Agora você pode ligar:

myfunc.call(obj_a);

Qual seria o alerta FOO. O contrário, passando obj_b alertaria BAR!!. A diferença entre .call() e .apply() é que .call() leva uma lista separada por vírgulas se você estiver passando argumentos para sua função e .apply() precisa de uma matriz.

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

Portanto, você pode facilmente escrever uma função hook usando o método apply(). Por exemplo, queremos adicionar um recurso ao método jQuerys .css(). Podemos armazenar a referência da função original, sobrescrever a função com código personalizado e chamar a função armazenada.

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

Como o objeto magic arguments é um array como objeto, podemos apenas passá-lo para apply(). Dessa forma, garantimos que todos os parâmetros sejam passados ​​para a função original.

275
jAndy

se :

_function.call(that, arg1, arg2, etc);

Onde that é o objeto que você deseja que this na função seja.

42
palswim

jQuery usa um método .call(...) para atribuir o nó atual a this dentro da função que você passa como o parâmetro.

EDIT:

Não tenha medo de olhar dentro do código do jQuery quando tiver alguma dúvida, está tudo em um JavaScript claro e bem documentado.

ou seja: a resposta a esta pergunta é em torno da linha 574,
callback.call( object[ name ], name, object[ name ] ) === false

16
Mic

Você pode usar a função bind para definir o contexto de this dentro de uma função.

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

Outro exemplo básico:

Não está funcionando:

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

Trabalhando:

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

Então, basicamente: basta adicionar .bind (isto) à sua função

5
Joery