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

发布于 2024-11-30 07:08:31 字数 718 浏览 0 评论 0原文

我一直在尝试理解 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,默认情况下返回对象的类型(动物)。 更新上述代码时,控制台输出“Zax say meow”,这似乎是正确的。

animal.prototype.name = 'Mammal';

当我在顶部代码块和

kitty.name = 'Zax';

底部

I've been trying to wrap my head around how javascript functions and scope work, and it just doesn't make sense to me. Can someone please explain why the following code outputs: 'animal says meow' instead of 'kitty says meow'?

(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 pointed out in the comments that console.log calls toString when it's passed an object, which by default returns the object's type (animal). When I update the above code with

animal.prototype.name = 'Mammal';

in the top block of code, and

kitty.name = 'Zax';

in the bottom, the console outputs 'Zax says meow', which seems about right.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴梦一场 2024-12-07 07:08:31

这段代码中的(function($) {})(jQuery)

(function($){}) 声明了该函数。然后(jQuery)立即调用传入 jQuery 对象的函数。

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

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

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

(function($) {})(jQuery)

in this code (function($){}) declares the function. Then (jQuery) imediately calls the function passing in the jQuery object.

so the first block of code passes in jQuery and the window object. Animal is added to the window object, which is the global scope.

in the second block a click event is added to an element and kitty.sayHi is passed in as the event handler. However if the event handler was not proxied then the this keyword in the eventhandler would return the element that has triggered the event. So by using the proxy the scope of the eventhandler becomes kitty.

I hope that is correct, this is new to me also.

迷你仙 2024-12-07 07:08:31

更新: kittyAnimal实例。所以它永远不会说小猫。所有这些代理包装器都是小心的误导。

让我们看看:

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

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

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


现在 jquery.proxy 允许您更改函数的上下文:jQuery.proxy( functionName, context ) - 所以在functionName中,this引用contextthis == context)。

$.proxy(kitty.sayHi, kitty) 表示调用 sayHikitty 作为上下文传递。

现在 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

Update: kitty is an instance of Animal. So it'll never say kitty. All those proxy wrappers are careful misdirections.

Lets see:

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

Just a disguise to say: window.Animal = function(){};

You're creating an anonymous function passing jQuery and window object to it and executing it immediately. This creates Animal class in window scope


Now jquery.proxy allows you to change the context of a function: jQuery.proxy( functionName, context ) - so inside functionName, this refers to context (this == context).

$.proxy(kitty.sayHi, kitty) says call sayHi passing kitty as context.

Now kitty = new Animal (this is called a closure actaully since you're accessing parent function's variable), so 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);

So when the click handler is called, its actually Animal.sayHi.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文