Понимание.$ прокси - () в jQuery



С docs Я понимаю, что .proxy() изменит область действия функции, передаваемой в качестве аргумента. Может кто-нибудь объяснить мне это лучше? Зачем нам это делать?

417   4  

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

    Ничего не найдено.