Как передать контекст this функции? - PullRequest
191 голосов
/ 02 сентября 2010

Я думал, что это было бы то, что я мог бы легко гуглить, но, возможно, я не задаю правильный вопрос ...

Как мне установить, что "this" ссылается на данную функцию javascript?

например, как с большинством функций jQuery, таких как:

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

Как мне написать / вызвать мои собственные автономные функции, которые имеют соответствующую ссылку "this" при вызове? Я использую jQuery, поэтому, если есть способ, специфичный для jQuery, это было бы идеально.

Ответы [ 5 ]

279 голосов
/ 02 сентября 2010

Javascripts .call() и .apply() методы позволяют вам установить контекст для функции.

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

var obj_a = {
    name:  "FOO"
};

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

Теперь вы можете вызывать:

myfunc.call(obj_a);

Что бы предупредить FOO.Наоборот, прохождение obj_b предупредит BAR!!.Разница между .call() и .apply() заключается в том, что .call() принимает список через запятую, если вы передаете аргументы своей функции, а .apply() нужен массив.

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

Следовательно, вы можетелегко написать функцию hook, используя метод apply().Например, мы хотим добавить функцию в метод jQuerys .css().Мы можем сохранить исходную ссылку на функцию, переписать функцию с помощью пользовательского кода и вызвать сохраненную функцию.

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

Поскольку магический объект arguments является массивом, подобным объекту, мы можем просто передать его в apply().Таким образом, мы гарантируем, что все параметры переданы исходной функции.

42 голосов
/ 02 сентября 2010

Использование :

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

Где that - это объект, который вы хотите this в функции.

16 голосов
/ 02 сентября 2010

jQuery использует метод .call(...), чтобы присвоить текущему узлу this внутри функции, которую вы передаете в качестве параметра.

РЕДАКТИРОВАТЬ:

Не 'Не бойтесь заглядывать в код jQuery, когда у вас есть сомнения, все это в ясном и хорошо документированном Javascript.

т.е. ответ на этот вопрос находится в строке 574,callback.call( object[ name ], name, object[ name ] ) === false

10 голосов
/ 15 июня 2017

Вы можете использовать функцию bind , чтобы установить контекст this внутри функции.

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"
5 голосов
/ 19 марта 2019

Другой базовый пример:

НЕ работает:

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

Рабочая:

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

Так что в основном: просто добавьте .bind (this) к вашей функции

...