请帮助我理解 Javascript 匿名函数和 jQuery .proxy()
我一直在尝试理解 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技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这段代码中的(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.
更新:
kitty
是Animal
的实例。所以它永远不会说小猫。所有这些代理包装器都是小心的误导。让我们看看:
只是一个伪装:
window.Animal = function(){};
您正在创建一个匿名函数,将 jQuery 和 window 对象传递给它并立即执行它。这将在
window
范围内创建Animal
类现在 jquery.proxy 允许您更改函数的上下文:
jQuery.proxy( functionName, context )
- 所以在functionName
中,this
引用context
(this == context
)。$.proxy(kitty.sayHi, kitty)
表示调用sayHi
将kitty
作为上下文传递。现在
kitty = new Animal
(这实际上称为闭包,因为您正在访问父函数的变量),所以this
->Animal
因此,当调用点击处理程序时,它实际上是
Animal.sayHi
。Update:
kitty
is an instance ofAnimal
. So it'll never say kitty. All thoseproxy
wrappers are careful misdirections.Lets see:
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 inwindow
scopeNow jquery.proxy allows you to change the context of a function:
jQuery.proxy( functionName, context )
- so insidefunctionName
,this
refers tocontext
(this == context
).$.proxy(kitty.sayHi, kitty)
says callsayHi
passingkitty
as context.Now
kitty = new Animal
(this is called a closure actaully since you're accessing parent function's variable), sothis
->Animal
So when the click handler is called, its actually
Animal.sayHi
.