Пожалуйста, помогите мне понять анонимные функции Javascript и jQuery .proxy () - PullRequest
7 голосов
/ 18 августа 2011

Я пытался обернуть голову, как работают функции javascript и область видимости, но для меня это не имеет смысла. Может кто-нибудь объяснить, почему выводится следующий код: «животное говорит мяу» вместо «котенок говорит мяу»?

(function($, exports){
  var animal = function(){};
  exports.Animal = animal;
})(jQuery, window);

(function($, Animal){
  var kitty = new Animal;
  kitty.sayHi = function(){
    console.log(this);
    console.log('says meow');
  }
  $($.proxy(function(){
    $('#js_test').click($.proxy(kitty.sayHi, kitty));
  }, kitty))
})(jQuery, Animal);

UPDATE

@ FunkyFresh указал в комментариях, что console.log вызывает toString при передаче объекта, который по умолчанию возвращает тип объекта (animal). Когда я обновляю приведенный выше код с

animal.prototype.name = 'Mammal';

в верхнем блоке кода и

kitty.name = 'Zax';

внизу консоль выводит «Zax говорит мяу», что кажется правильным.

Ответы [ 2 ]

2 голосов
/ 18 августа 2011

Обновление: kitty - это экземпляр из Animal. Так что это никогда не скажет Китти. Все эти proxy обертки - это осторожные неправильные указания.

Посмотрим:

(function($, exports){
  var animal = function(){};
  exports.Animal = animal;
})(jQuery, window);

Просто маскировка, чтобы сказать: window.Animal = function(){};

Вы создаете анонимную функцию, передавая ей jQuery и объект window и немедленно ее выполняете. Это создает Animal класс в window scope


Теперь jquery.proxy позволяет вам изменять контекст функции: jQuery.proxy( functionName, context ) - поэтому внутри functionName, this относится к context (this == context).

$.proxy(kitty.sayHi, kitty) говорит, что звонок sayHi передает kitty в качестве контекста.

Теперь kitty = new Animal (это на самом деле называется замыканием, поскольку вы обращаетесь к переменной родительской функции), поэтому this -> Animal

(function($, Animal){

  // create a new instance of Animal, assign it to local variable kitty
  var kitty = new Animal;

  // assign sayHi to kitty object
  kitty.sayHi = function(){
    console.log(this);
    console.log('says meow');
  }


  // $() shortcut that says run this code on DOM ready
  $($.proxy(function(){   
    // this proxy almost does nothing as we do not refer to this object insdie it

    // says on click of js_Test, call kitty.sayHi with context = kitty
    $('#js_test').click($.proxy(kitty.sayHi, kitty));

  }, kitty))

})(jQuery, Animal);

Таким образом, когда вызывается обработчик щелчка, он на самом деле Animal.sayHi.

2 голосов
/ 18 августа 2011

(функция ($) {}) (jQuery)

в этом коде (функция ($) {}) объявляет функцию.Затем (jQuery) немедленно вызывает функцию, передающую объект jQuery.

, поэтому первый блок кода переходит в jQuery и объект окна.Animal добавляется к объекту окна, который является глобальной областью действия.

во втором блоке событие click добавляется к элементу, и kitty.sayHi передается как обработчик события.Однако если обработчик события не был проксирован, тогда ключевое слово this в обработчике события вернет элемент, вызвавший событие.Таким образом, при использовании прокси область действия обработчика событий становится китти.

Надеюсь, это правильно, это также ново для меня.

...