I'm very new to JS and I have been playing around with Jasmine.
In Jasmine, I can see a method called spyOn, which does inspect/spy the functions.
How does this works in js? Coming from Java background is it a proxy? How to write one?
You can find the precise implementation on GitHub, but here is a simplified explanation:
function mySpy(obj, methodName) {
// remember the original method
var originalMethod = obj[methodName];
// ... then replace it with a method that ...
obj[methodName] = function () {
// ... does whatever additional thing it wants to do ...
console.log(methodName + " called, first argument: " + arguments[0]);
// ... and then calls the original method with the same arguments,
// and returns the result.
return originalMethod.apply(this, arguments);
};
}
Now you can do this:
var o = {
inc: function (x) { return x + 1; }
};
mySpy(o, "inc");
console.log(o.inc(13));
This will output
inc called, first argument: 13
14
Three important things for you to know, coming from a Java background, are
In JavaScript, it is not a problem to change an object's methods after the fact, dynamically. Calling someObj.someMethod = someOtherFunction is perfectly valid. (To be 100% precise, you may not actually be overwriting the original method, because it may be somewhere up the prototype chain, instead of on the object itself. That's an advanced topic though, and not very important here. Also, Java's distinction beween methods and class members doesn't apply to JavaScript.)
The special "variable" arguments inside a function contains whatever arguments the function was called with. In Java terms, imagine that someMethod(Foo x1, Bar x2) always has an implicit second signature of the type someMethod(Object... arguments), meaning you could always use x1 and arguments[0] interchangeably.
obj.someName and obj["someName"] are entirely equivalent in JavaScript. Because of this, you can easily access/change an object's properties using the property name as a string, something that in Java you would have to use reflection for.
Related
Stylistically, I prefer this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
};
To this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
};// var Filter = function(){...}
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?
I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.
Functionally, are there any drawbacks to structuring my code this way?
Will adding a prototypical method to a prototype object inside the
constructor function's body (i.e. before the constructor function's
expression statement closes) cause unexpected scoping issues?
Yes, there are drawbacks and unexpected scoping issues.
Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.
There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.
There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:
Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)
And, of course, if someone used:
Object.create(Filter.prototype)
without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.
From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
this.checkProduct = function( product ){
// run some checks
return is_match;
}
};
There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.
The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:
var Counter = function(initialValue){
var value = initialValue;
// product is a JSON object
Counter.prototype.get = function() {
return value++;
}
};
var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get()); // outputs 10, should output 0
Demonstration of the problem: http://jsfiddle.net/jfriend00/c7natr3d/
This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.
While the other answers have focused on the things that are wrong with assigning to the prototype from inside the constructor, I'll focus on your first statement:
Stylistically, I prefer this structure
Probably you like the clean encapsulation that this notation offers - everything that belongs to the class is properly "scoped" to it by the {} block. (of course, the fallacy is that it is scoped to each run of the constructor function).
I suggest you take at the (revealing) module patterns that JavaScript offers. You get a much more explicit structure, standalone constructor declaration, class-scoped private variables, and everything properly encapsulated in a block:
var Filter = (function() {
function Filter(category, value) { // the constructor
this.category = category;
this.value = value;
}
// product is a JSON object
Filter.prototype.checkProduct = function(product) {
// run some checks
return is_match;
};
return Filter;
}());
The first example code kind of misses the purpose of the prototype. You will be recreating checkProduct method for each instance. While it will be defined only on the prototype, and will not consume memory for each instance, it will still take time.
If you wish to encapsulate the class you can check for the method's existence before stating the checkProduct method:
if(!Filter.prototype.checkProduct) {
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
}
There is one more thing you should consider. That anonymous function's closure now has access to all variables inside the constructor, so it might be tempting to access them, but that will lead you down a rabbit hole, as that function will only be privy to a single instance's closure. In your example it will be the last instance, and in my example it will be the first.
Biggest disadvantage of your code is closing possibility to override your methods.
If I write:
Filter.prototype.checkProduct = function( product ){
// run some checks
return different_result;
}
var a = new Filter(p1,p2);
a.checkProduct(product);
The result will be different than expected as original function will be called, not my.
In first example Filter prototype is not filled with functions until Filter is invoked at least once. What if somebody tries to inherit Filter prototypically? Using either nodejs'
function ExtendedFilter() {};
util.inherit(ExtendedFilter, Filter);
or Object.create:
function ExtendedFilter() {};
ExtendedFilter.prototype = Object.create(Filter.prototype);
always ends up with empty prototype in prototype chain if forgot or didn't know to invoke Filter first.
Just FYI, you cannot do this safely either:
function Constr(){
const privateVar = 'this var is private';
this.__proto__.getPrivateVar = function(){
return privateVar;
};
}
the reason is because Constr.prototype === this.__proto__, so you will have the same misbehavior.
Stylistically, I prefer this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
};
To this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
};// var Filter = function(){...}
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?
I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.
Functionally, are there any drawbacks to structuring my code this way?
Will adding a prototypical method to a prototype object inside the
constructor function's body (i.e. before the constructor function's
expression statement closes) cause unexpected scoping issues?
Yes, there are drawbacks and unexpected scoping issues.
Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.
There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.
There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:
Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)
And, of course, if someone used:
Object.create(Filter.prototype)
without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.
From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
this.checkProduct = function( product ){
// run some checks
return is_match;
}
};
There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.
The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:
var Counter = function(initialValue){
var value = initialValue;
// product is a JSON object
Counter.prototype.get = function() {
return value++;
}
};
var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get()); // outputs 10, should output 0
Demonstration of the problem: http://jsfiddle.net/jfriend00/c7natr3d/
This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.
While the other answers have focused on the things that are wrong with assigning to the prototype from inside the constructor, I'll focus on your first statement:
Stylistically, I prefer this structure
Probably you like the clean encapsulation that this notation offers - everything that belongs to the class is properly "scoped" to it by the {} block. (of course, the fallacy is that it is scoped to each run of the constructor function).
I suggest you take at the (revealing) module patterns that JavaScript offers. You get a much more explicit structure, standalone constructor declaration, class-scoped private variables, and everything properly encapsulated in a block:
var Filter = (function() {
function Filter(category, value) { // the constructor
this.category = category;
this.value = value;
}
// product is a JSON object
Filter.prototype.checkProduct = function(product) {
// run some checks
return is_match;
};
return Filter;
}());
The first example code kind of misses the purpose of the prototype. You will be recreating checkProduct method for each instance. While it will be defined only on the prototype, and will not consume memory for each instance, it will still take time.
If you wish to encapsulate the class you can check for the method's existence before stating the checkProduct method:
if(!Filter.prototype.checkProduct) {
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
}
There is one more thing you should consider. That anonymous function's closure now has access to all variables inside the constructor, so it might be tempting to access them, but that will lead you down a rabbit hole, as that function will only be privy to a single instance's closure. In your example it will be the last instance, and in my example it will be the first.
Biggest disadvantage of your code is closing possibility to override your methods.
If I write:
Filter.prototype.checkProduct = function( product ){
// run some checks
return different_result;
}
var a = new Filter(p1,p2);
a.checkProduct(product);
The result will be different than expected as original function will be called, not my.
In first example Filter prototype is not filled with functions until Filter is invoked at least once. What if somebody tries to inherit Filter prototypically? Using either nodejs'
function ExtendedFilter() {};
util.inherit(ExtendedFilter, Filter);
or Object.create:
function ExtendedFilter() {};
ExtendedFilter.prototype = Object.create(Filter.prototype);
always ends up with empty prototype in prototype chain if forgot or didn't know to invoke Filter first.
Just FYI, you cannot do this safely either:
function Constr(){
const privateVar = 'this var is private';
this.__proto__.getPrivateVar = function(){
return privateVar;
};
}
the reason is because Constr.prototype === this.__proto__, so you will have the same misbehavior.
I'm learning JavaScript. Most of the materials says JavaScript only has 3 primitive types: Number, Boolean, String and 2 special primitive value: null, undefined. And everything else is Object type including array, function, reg expression.
I can easily imagine that array is some kind of special object, but why function also object type? There's nothing similar between object and function. How to implement a special object to work like a function? I have no idea.
There is no way to implement an object to work like a function, but you can use a function as an object.
var a = function(){}
a.x = 5;
console.log(a.x);
The reason everything is an object like that is just a design choice that, for some, is considered elegant. I particularly don't agree, but people don't agree with things, in general.
Also, I should note that a point that is probably being made is that JS functions are first-class. This means you can use a function like you could use any other value, which includes sending them as arguments to other functions and returning functions from functions and so on. Examples below:
// return functions from function
function create_a_function_that_doubles_numbers(){
return function(a){ return a*2; }
}
var double_number = create_a_function_that_doubles_numbers();
console.log(double_number(5)); // 10
// sending a function to a function
function call_twice(f){
f(); f();
};
function shout(){
alert("HEY");
};
call(shout);
// Here we send "shout" to "call_twice" which... calls it twice,
// so a "HEY" popup appears two times.
Other than tricking existing functions that already implement this as something, why would you want to write a javascript function so that you need to alter its context (via .call or .apply) rather than explicitly passing the "context" as another parameter? Is there a performance benefit?
Example:
function tryIncrement(inc, context) {
context = context || this; // just so we can reuse same fn for the example
if( typeof context.val!= typeof 1|| typeof inc != typeof 1 ) return false;
context.val += inc;
return true;
}
var a = {name: 'A', val: 5}, b = {name: 'B', val: 20};
// reassign internal context
for(var i = 0, n = [1,3,"not a num",5]; i < n.length; i++) {
if( tryIncrement.call(a, n[i]) ) console.log('incremented', i, n[i], a);
else console.log('failed to increment', i, n[i], a);
}
// provide explicit context;
// could just as easily declared function so context was first param
// so it looked the same as previous implementation
for(var i = 0, n = [1,3,"not a num",5]; i < n.length; i++) {
if( tryIncrement(n[i], b) ) console.log('incremented', i, n[i], b);
else console.log('failed to increment', i, n[i], b);
}
There are many cases where you may wish to use this instead of passing an extra parameter. Consider the following function for example:
Function.prototype.async = function () {
setTimeout.bind(null, this, 0).apply(null, arguments);
};
This function allows us to defer a function call as follows:
alert.async("This will display later.");
alert("This will display first.");
You can see the demo here: http://jsfiddle.net/AjwQu/
Instead of binding the function to this we could have passed it as a parameter instead:
function async(funct) {
setTimeout.bind(null, funct, 0).apply(null, [].slice.call(arguments, 1));
}
We would use it like this now:
async(alert, "This will display later.");
alert("This will display first.");
The result is the same: http://jsfiddle.net/63dBF/
However to get the arguments we have to use [].slice.call(arguments, 1) instead. In the first example we could simply use arguments as the function was not a part of the argument list.
Everything has it's advantages and disadvantages. You just need to know what to use when. Hope this helps a bit.
Bonus: It's really easy to convert a function that uses this into a function that accepts an extra parameter and vice versa. First let's define a few utility functions:
var functProto = Function.prototype;
var bind = functProto.bind;
var bindable = bind.bind(bind);
var callable = bindable(functProto.call);
var appliable = bindable(functProto.apply);
The bindable function allows you to create a bindable version of an existing function which when called returns a new function bound to the given arguments.
The callable function allows you to create a callable version of an existing function which when called calls the existing function with the given arguments and this pointer.
The appliable function allows you to create an appliable version of an existing function which when called applies the given arguments and this pointer to the existing function.
Then given the function in the first example we can create the function in the second example as follows:
var async = callable(functProto.async);
See the demo here: http://jsfiddle.net/3dSBS/
Similarly we can convert the function in the second example into the function in the first example as follows:
Function.prototype.async = function () {
return async.apply(null, [this].concat([].slice.call(arguments)));
};
See the demo here: http://jsfiddle.net/rJQyS/
As you can see it's much easier to write a function using this and then construct the function accepting the context as a parameter from it than the other way around.
As far as I can tell the use of this isn't really any different than
another parameter, it just has a more complicated way of being
modified.
I think the easiest way to answer your question is to imagine if the creator of the base Javascript language had followed your conventions.
A world without this
A world without this is a scary noisy place with lots of excessive duplication:
var arr = [1,2,3,4];
arr.reverse(arr); //4321
More opportunities for misleading or verbose syntax
var str = "stringtobesplit";
"abiglongstringnotbeingsplit".split(str,":");
String.prototype.split(str,":");
And its not at all rid of apply at least:
Math.max.apply(arr); //didn't add the initial `this` since it doesn't exist
Effectively there would be a choice between creating only global functions, or creating functions on prototypes or objects that made assumptions about the types of the arguments it was receiving but didn't enforce those assumptions. For instance imagine the toString method in our fantasy world.
You could either create a global toString method which would take in an object of every type ever, and try to make them all work, or you could have a function on the prototypes of each type as it works currently, with no enforcement that it would be called on that type. Someone could call
Array.prototype.toString(str)
And we would need to handle it gracefully (for what its worth doing this with apply seems to revert to the Object.prototype.toString and returns [Object String]). So we would need to identify the correct prototype method to call in those cases, which means my guess is that the convention would be to call
str.toString(str)
or something along those lines.
So whats the point?
this is built to handle the common case for javascript methods on the prototype chain. It gives us a shorthand to allow an object to act on itself without duplicating the call to it or having to know exactly what its prototype is. Without it, we would either have to have no functions on objects, or would have to explicitly call the function on itself every time, introducing extra syntax and potential errors.
call and apply are the exception cases, and apply at least would have uses even if this went away. Its never a good idea to write your apis to the exception cases. If you're creating object oriented code, you should use this as an easy way to refer to the object that is the context for the call. If you write this well, then call and apply should be used rarely and in special situations.
TL;DR - this was designed as part of Javascript for a reason, use it when you're creating methods on objects for more clear and understandable syntax.
When you do object oriented programming your functions WILL depend on the context and it does not make sense do provide it as a parameter, as this would deafeat the purpose of object oriented programming.
It also makes sense to provide an implicit context for callbacks. You do not have to remember the correct order of the parameters if you only need the context. You would not have to use parameters at all in that case. So instead of
function mayCallback(param1, param2, context)
you could just write
function myCallback()
and use this, if you do not need param1 and param2.
To address my main purpose -- is there a performance benefit using this over a function parameter? -- the answer seems to be no:
http://jsperf.com/function-context-vs-parameter
Although there seems to be a slight benefit (may not be significant, however) around using parameter values instead of instance (this) variables within objects.
(Please test for yourself and comment if it's different)
Regarding the purpose being addressed by the other answers: there are some neat use cases as pointed out by #Aadit, maintainability is debatably a personal preference, but like #ben336 said if you're working with Objects (and thus OOP) then this can be more useful.
The ECMAScript 5th-edition native function bind may be an interesting bridge between the two worlds, or at least a time-sucking tangent to explore.
The instance vs parameter values test referenced above may also be a good example of my point -- if you're building a static library of functionality, you can "hijack" obj.callback2 by scoping to a different this, or just call obj.callback directly on your alternate context.
I study JavaScript Proxy Pattern, but I still do not get, where I can benefit from it. I would therefore like to provide you with two examples and kindly ask you to point at the difference between them.
Please, take a look at the code below:
What is the difference between the two addEventListener calls? One of them calls handleDrop in regular way. The other uses Proxy Pattern.
What will I gain using Proxy pattern approach?
I tested both functions, and they both call handleDrop successfully.
DndUpload.prototype.buildDropZone = function ()
{
var self = this,
this.dropZone.addEventListener('drop', function (e) { self.handleDrop.call(self, e) }, false);
this.dropZone.addEventListener('drop', self.handleDrop, false);
DndUpload.prototype.handleDrop = function (e)
{
alert("test");
...
};
}
You can provide me with good reference which contains very clear explanation of Proxy Pattern in JavaScript.
So what you're describing in your example isn't so much a demonstration of the Proxy pattern as much as a demonstration of confusion regarding the "calling object" and how it works in JavaScript.
In JavaScript, functions are "first-class." This essentially means that functions are data just like any other data. So let's consider the following situation:
var fn = (function () { return this.x; }),
a = {
x : 1,
fn : fn,
},
x = 2,
nothing = (function (z) { return z; });
So, we have an object a, which has two properties: fn and x. We also have variables x, fn (which is a function returning this.x), and nothing (which returns whatever it gets passed).
If we evaluate a.x, we get 1. If we evaluate x, we get 2. Pretty simple, eh? Now, if we evaluate nothing(a.x), then we get 1. That's also very simple. But it's important to realize that the value 1 associated with the property a.x is not in any way connected to the object a. It exists independently and can be passed around simply as a value.
In JavaScript, functions work the same way. Functions that are properties (often called "methods") can be passed as simple references. However, in doing so, they can become disconnected from their object. This becomes important when you use the this keyword inside a function.
The this keyword references the "calling object." That's the object that is associated with a function when that function is evaluated. There are three basic ways to set the calling object for a function:
If the function is called using the dot operator (e.g. a.fn()), the relevant object (in the example, a) is set as the calling object.
If the function is called using the function's call or apply properties, then you can explicitly set the calling object (we'll see why this is useful in a second).
If no calling object is set through method 1 or method 2, the global object is used (in a browser, this is typically called window).
So, back to our code. If we call a.fn(), it will evaluate as 1. That's expected because the this keyword in the function will be set to a due to the use of the dot operator. However, if we call simply fn(), it will return 2 because it is referencing the x property of the global object (meaning our global x is used).
Now, here's where things get tricky. What if you called: nothing(a.fn)()? You might be surprised that the result is 2. This is because passing a.fn into nothing() passes a reference to fn, but does not retain the calling object!
This is the same concept as what's going on in your coding example. If your function handleDrop were to use the this keyword, you would find it has a different value depending on which handler form you use. This is because in your second example, you're passing a reference to handleDrop, but as with our nothing(a.fn)() example, by the time it gets called, the calling object reference is lost.
So let's add something else to the puzzle:
var b = {
x : 3
};
You'll note that while b has an x property (and therefore satisfies the requirements for fn's use of this), it doesn't have a property referencing fn. So if we wanted to call the fn function with its this set to b, it might seem we need to add a new property to b. But instead we can use the aforementioned apply method on fn to explicitly set b as the calling object:
fn.apply(b); //is 3
This can be used to "permanently" bind a calling object to a function by creating a new function "wrapper." It's not really permanently binding, it's just creating a new function that calls the old function with the desired calling object. Such a tool is often written like so:
Function.prototype.bind = function (obj) {
var self = this;
return function() {
return self.apply(obj, arguments);
};
};
So after executing that code, we could do the following:
nothing(a.fn.bind(a))(); //is 1.
It's nothing tricky. In fact, the bind() property is built into ES5 and works pretty much like the simple code above. And our bind code is actually a really complicated way to do something that we can do more simply. Since a has fn as a property, we can use the dot operator to call it directly. We can skip all the confusing use of call and apply. We just need to make sure when the function gets called, it gets called using the dot operator. We can see how to do it above, but in practice, it's far simpler and more intuitive:
nothing(function () { return a.fn(); })(); //is 1
Once you have an understanding of how data references can be stored in closure scope, how functions are first-class objects, and how the calling object works, this all becomes very simple to understand and reasonably intuitive.
As for "proxies," those also exploit the same concepts to hook into functions. So, let's say that you wanted to count the number of times a.fn gets called. You can do that by inserting a proxy, like so (making use of some concepts from our bind code from above):
var numCalls = (function () {
var calls = 0, target = a.fn;
a.fn = (function () {
calls++;
return target.apply(a, arguments);
});
return (function () {
return calls;
});
}());
So now, whenever you call numCalls(), it will return the number of times a.fn() was called without actually modifying the functionality of a.fn! which is pretty cool. However, you must keep in mind that you did change the function referenced by a.fn, so looking way back to the beginning of our code, you'll notice that a.fn is no longer the same as fn and can't be used interchangeably anymore. But the reasons should now be pretty obvious!
I know that was basically a week of JavaScript education in a couple pages of text, but that's about as simple as it gets. Once you understand the concepts, the functionality, usefulness, and power of many JavaScript patterns become very simple to understand.
Hope that made things clearer!
UPDATE: Thanks to #pimvdb for pointing out my unnecessary use of [].slice.call(arguments, 0). I have removed it because it's, well, unnecessary.
Basically, passing self.handleDrop directly is functionally equivalent to passing the following function:
function() {
return self.handleDrop.apply(this, arguments);
}
because everything is passed through to the original function:
The this value
The arguments
The return value
With this in mind, compare your functions as follows:
function(e) { self.handleDrop.call(self, e) }
function() { return self.handleDrop.apply(this, arguments); }
The difference with your proxy way is:
It doesn't pass the return value through.
It doesn't pass all arguments through (only the first, e)
It doesn't pass the this value through, but uses a predefined one: self.
Now, the first two items don't make a difference here, because addEventListener doesn't care about the return value, and it also only passes one argument anyway.
But the third item is important: it sets a different this value in the function. By default, this is the element you bind the event to (it it set by the browser). Using the proxy way, you can set another this value.
Now, in your snippet it is not fully clear why you're setting a prototype function each time buildDropZone is called. Usually you define prototype functions only once. But when your handler handleDrop is called using the proxy way, this refers to the DndUpload instance, which is consistent with prototype functions in general.
Consider the code below:
function printThis() {
console.log(this);
}
var someObject = {
performTest : function() {
var self = this;
someOtherObject.higherOrderFunction(printThis);
someOtherObject.higherOrderFunction(function(){printThis.call(self)});
}
}
var someOtherObject = {
higherOrderFunction : function(f) {
f();
}
}
What will someOtherObject.higherOrderFunction(printThis) return?
How about someOtherObject.higherOrderFunction(function(){printThis.call(self)})
The answer to the first question depends on who and how you call someObject.performTest(). If I just call someObject.performTest() from a global context, it will probably print Window.
The second one will always print the someObject instance no matter what.
The closures or 'proxy pattern' as you call it comes in handy when you want to control exactly the execution context of a function.
Note: this in javascript does not behave like it does in other languages(in Java for example).