Як передати цей контекст функції?


213

Я подумав, що це щось, що я міг легко гугл, але, можливо, я не задаю правильного питання ...

Як встановити будь-яке "це" в даній функції javascript?

наприклад, як у більшості функцій jQuery, таких як:

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

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


Можливий дублікат: stackoverflow.com/questions/520019 / ...
user123444555621

Я знаю, що це давнє запитання, але для інших, хто приземлився тут, дивіться jQuery$.proxy
RyBolt

Відповіді:


303

Яваскрипти .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()метод. Наприклад, ми хочемо додати функцію до .css()методу jQuerys . Ми можемо зберігати оригінальну посилання на функцію, перезаписувати функцію спеціальним кодом та викликати збережену функцію.

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

Оскільки магічний argumentsоб’єкт є масивом, подібним до об'єкта, ми можемо просто передати його apply(). Таким чином ми гарантуємо, що всі параметри передаються до вихідної функції.


4
Просто прикольний прихисток: якщо вам потрібно повторно зателефонувати до функції obj_a, наприклад, ви можете створити її копію var boud_myfunc = myfunc.bind(obj_a)та просто зателефонувати bound_myfunc()за потребою.
wbadart

44

Використанняfunction.call :

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

Де thatзнаходиться об’єкт, який ви хочете thisу функції.


1
function- зарезервоване ключове слово; розгляньте можливість оновлення своєї відповіді, щоб вона включала названу функцію, оскільки function.call(...)JavaScript не є дійсним.
Даніель Аллен

1
@DanielAllen: Без визначення того, яку назву функції вибірки я б надавав, код все одно призведе до помилки JS. Але я оновив назву функції вибірки.
palswim

16

jQuery використовує .call(...)метод для призначення поточного вузла thisвсередині функції, яку ви передаєте в якості параметра.

Редагувати:

Не бійтеся заглядати всередину коду jQuery, коли у вас є сумніви, все це в чіткому та добре задокументованому Javascript.

тобто відповідь на це запитання - приблизно в рядку 574,
callback.call( object[ name ], name, object[ name ] ) === false


12

Ви можете використовувати функцію прив'язки, щоб встановити контекст thisфункції.

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

12

Ще один основний приклад:

Не працює:

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 (це) до своєї функції


Це має бути прийнятою відповіддю. Набагато простіший синтаксис, набагато простіше на розум ... хороша робота Joery
nenea
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.