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.
(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.