Понимание.$ прокси - () в jQuery
С docs Я понимаю, что .proxy() изменит область действия функции, передаваемой в качестве аргумента. Может кто-нибудь объяснить мне это лучше? Зачем нам это делать?
4 ответов:
что это в конечном итоге делает это гарантирует, что значение
thisв функции будет значение, которое вы желаете.общий пример-в
setTimeoutэто происходит внутриclickобработчик.вот это:
$('#myElement').click(function() { // In this function, "this" is our DOM element. $(this).addClass('aNewClass'); });намерение достаточно проста. Когда
myElementщелкается, он должен получить классaNewClass. Внутри обработчикаthisпредставляет элемент, который был нажат.но что, если мы хотели небольшой задержкой добавление класса? Мы могли бы использовать
setTimeoutчтобы выполнить это, но беда в том, что какую бы функцию мы ни давалиsetTimeout, стоимостьюthisвнутри этой функции будетwindowвместо нашей стихии.$('#myElement').click(function() { setTimeout(function() { // Problem! In this function "this" is not our element! $(this).addClass('aNewClass'); }, 1000); });так что мы можем сделать вместо этого, чтобы позвонить
$.proxy(), отправив ему функцию и значение, которое мы хотим присвоитьthis, и он вернет функцию, которая сохранит это значение.$('#myElement').click(function() { // ------------------v--------give $.proxy our function, setTimeout($.proxy(function() { $(this).addClass('aNewClass'); // Now "this" is again our element }, this), 1000); // ---^--------------and tell it that we want our DOM element to be the // value of "this" in the function });после того, как мы дали
$.proxy()функции и значение мы хотим дляthis, он возвращает функцию, которая будет гарантировать, чтоthisправильно настроен.как это сделать? Он просто возвращает анонимную функцию, которая звонки наша функция с помощью
.apply()метод, который позволяет явно задать значениеthis.упрощенный взгляд на возвращаемую функцию может выглядеть так:
function() { // v--------func is the function we gave to $.proxy func.apply( ctx ); // ----------^------ ctx is the value we wanted for "this" (our DOM element) }так что эта анонимная функция дается
setTimeoutи все это выполнить наш первоначальный функция с правильнымthisконтексте.
не вдаваясь в подробности (что было бы необходимо, потому что речь идет о контекст в ECMAScript, то в этом контексте переменной etc.)
в ECMA - / Javascript есть три разных типа "контекстов":
- глобальный контекст
- контекстном функции
- eval контекст
каждый код выполняется в своем контекст исполнения. Есть один глобальный контекст и может быть много экземпляров контекстов функций (и eval). Теперь самое интересное:
каждый вызов функции входит в контекст выполнения функции. Контекст выполнения функции выглядит следующим образом:
Объект Активации
Scope Chain
в строкетак этой значение-это специальный объект, который связан с контекст выполнения. В ECMA - / Javascript есть две функции, которые могут изменить этой значение в контексте исполнения функции:
.call() .apply()если у нас есть функция
foobar()мы можем изменить этой значение по телефонам:foobar.call({test: 5});теперь мы могли получить доступ в
foobarобъект, который мы передали:function foobar() { this.test // === 5 }это точно
jQuery.proxy()делает. Это занимаетfunctionиcontext(который является не чем иным, как объектом) и ссылки функция путем вызова.call()или.apply()и возвращает новую функцию.
Я написал эту функцию:
function my_proxy (func,obj) { if (typeof(func)!="function") return; // If obj is empty or another set another object if (!obj) obj=this; return function () { return func.apply(obj,arguments); } }
та же цель может быть достигнута с помощью самостоятельного выполнения функции:
$('#myElement').click(function() { (function(el){ setTimeout(function() { // Problem! In this function "this" is not our element! el.addClass('colorme'); }, 1000); })($(this)); // self executing function });.colorme{ color:red; font-size:20px; }<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <script src="https://code.jquery.com/jquery-3.1.0.js"></script> <div id="myElement">Click me</div> </body> </html>
Comments