请帮我理解Javascript匿名函数和jQuery .proxy()

时间:2011-08-18 00:26:42

标签: javascript jquery anonymous-function

我一直试图围绕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);

更新

@FunkyFresh在评论中指出,当console.log传递一个对象时,它会调用toString,默认情况下会返回对象的类型(animal)。当我用

更新上面的代码时
animal.prototype.name = 'Mammal';
顶部代码块中的

kitty.name = 'Zax';
在底部,控制台输出'Zax说喵',这似乎是正确的。

2 个答案:

答案 0 :(得分:2)

(function($){})(jQuery)

在此代码中(function($){})声明该函数。然后(jQuery)立即调用传递jQuery对象的函数。

所以第一个代码块传递给jQuery和window对象。 Animal被添加到window对象中,这是全局范围。

在第二个块中,将click事件添加到元素中,并将kitty.sayHi作为事件处理程序传入。但是,如果事件处理程序未被代理,则eventhandler中的this关键字将返回触发事件的元素。因此,通过使用代理,事件处理程序的范围变为kitty。

我希望这是正确的,这对我来说也是新的。

答案 1 :(得分:2)

更新: kittyAnimal实例。所以它永远不会说小猫。所有这些proxy包装都是谨慎的误导。

让我们看看:

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

只是伪装成:window.Animal = function(){};

您正在创建一个匿名函数,将jQuery和window对象传递给它并立即执行它。这会在Animal范围

中创建window

现在jquery.proxy允许您更改函数的上下文:jQuery.proxy( functionName, context ) - 所以在functionName内,this引用contextthis == 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);

因此,当调用click处理程序时,它实际上是Animal.sayHi