Understanding jquery source code - javascript

I have recently started to delve deeper in to JavaScript and have come across this code construct in JQuery.
(function( window, undefined ) {
})(window)
Reading on stack overflow (and elsewhere) I have come to the conclusion that this is the same as
function foo(window, undefined) {
...
}
foo(window);
Am I correct in my assumption?
If so, what are the advantages of the former? (other than confusing newbs)

There are several things you need to know to make sense of it:
It is an anonymous function, which simply means it does not have a name.
The function is called immediately after it is declared. You see the open parenthesis on line 2, immediately after the function definition? That means, "call this function".
Only one parameter is passed to the function. That parameter is "window", which is the name of the global scope inside of a browser.
The function being called actually expects *2* parameters, but we're calling it with one. Javascript lets you call functions with more or fewer parameters than the function actually expects. There are ways of getting to the list of parameters that was passed.
Since we are only passing one parameter, the second parameter will automatically be set to "undefined". "undefined" is a special javascript value that means, get ready, "undefined".
It just so happens that we have also named our second parameter with the name "undefined". So in effect, we have created a local variable (parameters are very much like local variables) that is named undefined, and whose value is undefined.
Why on Earth did we do that? It is a way of ensuring that, within our anonymous function, if we refer to "undefined", it really will have the value of "undefined". If we didn't do that, and some crazy code outside of our scope redefined "undefined" (by saying something like "undefined = 42"), then we'd write code thinking we were referring to undefined but we'd actually be referring to 42. These shenanigans with passing 1 parameter but expecting 2, and calling the second one undefined, protects us from such nonsense.
I hope that's clear, let me know if it is not. I learned all that from Paul Irish's video mentioned above.

This is an anonymous function. It is created and then goes out of scope, which here is the advantage. It is created and instantiated immediately. What is good about this is that it is not going to collide with any function on the global namespace, and thus will not obliterate anything you may have included on the page.

It is an anonymous function, it has quite a few benefits, like being only active in the current scope. You can read more about it here.

Related

Calling vs invoking a function

Up to this point, I thought "calling" and "invoking" a function meant the same thing. However, in a YouTube tutorial it said to invoke a function by calling it. My first thought was that the wording was a mistake, but on W3Schools' page on Function Invocation, it says:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use invoke, because a
JavaScript function can be invoked without being called.
Okay, so there's a difference. What is it?
Your reference text:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use invoke, because a
JavaScript function can be invoked without being called.
Now let me rephrase it:
It is common to use the term "call a function" instead of "invoke a
function" ... In this tutorial, we will use the term invoke instead of call, because a
JavaScript function can be invoked indirectly like fn.call() and fn.apply() without being called directly like fn().
So, when I do fn(), it's invoked directly and when I do it like fn.call(), it's invoked indirectly but in both cases, the function is being invoked. Otherwise, I see no difference here and I can also say that I can call a function in many ways, for example:
fn(); // I'm calling it
fn.call(); // I'm calling it
fn.apply(); // I'm calling it
So, the difference is semantic but both are interchangeable, IMO. BTW, I wrote a comment above, under the question and I would like to put it here, which is:
IMO, that's a misleading statement. Maybe there are some indication of
call/apply or something else but it's totally confusing.
The difference is semantic and subtle. When you call a function, you are directly telling it to run. When you invoke a function, you are letting something run it.
There is one way to call a function:
myFunction()
Here, you are invoking the function (letting it run) by calling it directly.
There are many ways to invoke a function (given throughout different comments and answers). Here's one example:
function invoker(functionName) {
functionName()
}
invoker(myFunction)
Here, by calling invoker, you are invoking myFunction, which is being called indirectly.
Yes, in most cases we use both to refer the execution of a function.
There are 2 ways to reach place B from your HOME.
Direct/Automatic way (Invoke), i.e. if you choose first way, you do not need to walk. Someone will automatically take you to place B.
Indirect way (Call), i.e. if choose second way, you only need to reach A(by walk). Someone is there at place A to automatically take you to place B.
Have a look at the below image. I think it will clear your doubt.
In case of Calling, you originally refer to the statement that actually calls the function.
In case of Invoking, you indirectly refer to calling statement to actually invoke/run the function.
Many people use the term calling and invoking interchangeably but that's not right. There is a very slight difference between calling and invoking a function. In JavaScript functions can be invoked without being called which means that the code inside the body of the function can be executed without creating an object for the same. It is tied to the global object. When there is no individual object, the value of this is associated with the global object.
There is also a difference between call and apply, the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments. A different this object can be assigned when calling an existing function. this refers to the current object, the calling object. With call, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
So, the major difference between invoking and calling comes in terms of the this object. Calling let's you set the this value whereas invoking just ties it to the global object.
"function invoked" means a function got executed
"function called" means that a function was called by another function and then executed
"function invoked without being called" is a function that got self invoked without being called by another function
example of a self invoking function calling another function:
var f = (function() {
foo();
})(); ///() here means it self invoked -- without being called directly.
var foo = (function() {
///Do something here
});

Why JavaScript file starts with (function (undefined)? [duplicate]

Have you ever taken a look under the hood at the jQuery 1.4 source code and noticed how it's encapsulated in the following way:
(function( window, undefined ) {
//All the JQuery code here
...
})(window);
I've read an article on JavaScript Namespacing and another one called "An Important Pair of Parens," so I know some about what's going on here.
But I've never seen this particular syntax before. What is that undefined doing there? And why does window need to be passed and then appear at the end again?
The undefined is a normal variable and can be changed simply with undefined = "new value";. So jQuery creates a local "undefined" variable that is REALLY undefined.
The window variable is made local for performance reasons. Because when JavaScript looks up a variable, it first goes through the local variables until it finds the variable name. When it's not found, JavaScript goes through the next scope etc. until it filters through the global variables. So if the window variable is made local, JavaScript can look it up quicker.
Further information: Speed Up Your JavaScript - Nicholas C. Zakas
Undefined
By declaring undefined as an argument but never passing a value to it ensures that it is always undefined, as it is simply a variable in the global scope that can be overwritten. This makes a === undefined a safe alternative to typeof a == 'undefined', which saves a few characters. It also makes the code more minifier-friendly, as undefined can be shortened to u for example, saving a few more characters.
Window
Passing window as an argument keeps a copy in the local scope, which affects performance: http://jsperf.com/short-scope. All accesses to window will now have to travel one level less up the scope chain. As with undefined, a local copy again allows for more aggressive minification.
Sidenote:
Though this may not have been the intention of the jQuery developers, passing in window allows the library to be more easily integrated in server-side Javascript environments, for example node.js - where there is no global window object. In such a situation, only one line needs to be changed to replace the window object with another one. In the case of jQuery, a mock window object can be created and passed in for the purpose of HTML scraping (a library such as jsdom can do this).
Others have explained undefined. undefined is like a global variable that can be redefined to any value. This technique is to prevent all undefined checks from breaking if someone wrote say, undefined = 10 somewhere. An argument that is never passed is guaranteed to be real undefined irrespective of the value of the variable undefined.
The reason to pass window can be illustrated with the following example.
(function() {
console.log(window);
...
...
...
var window = 10;
})();
What does the console log? The value of window object right? Wrong! 10? Wrong! It logs undefined. Javascript interpreter (or JIT compiler) rewrites it this way -
(function() {
var window; //and every other var in this function
console.log(window);
...
...
...
window = 10;
})();
However, if you get the window variable as an argument, there is no var and hence no surprises.
I don't know if jQuery is doing it, but if you are redefining window local variable anywhere in your function for whatever reason, it is a good idea to borrow it from global scope.
window is passed in like that just in case someone decides to redefine the window object in IE, I assume the same for undefined, in case it's re-assigned in some way later.
The top window in that script is just naming the argument "window", an argument that's more local that the global window reference and it what the code inside this closure will use. The window at the end is actually specifying what to pass for the first argument, in this case the current meaning of window...the hope is you haven't screwed up window before that happens.
This may be easier to think of by showing the most typical case used in jQuery, plugin .noConflict() handling, so for the majority of code you can still use $, even if it means something other than jQuery outside this scope:
(function($) {
//inside here, $ == jQuery, it was passed as the first argument
})(jQuery);
Tested with 1000000 iterations. This kind of localization had no effect in performance. Not even a single millisecond in 1000000 iterations. This is simply useless.

How does "makeAddFunction" in Eloquent JS work?

I'm trying to learn Javascript by reading Eloquent Javacript. I'm on the chapter dealing with functions and I'm stuck trying to figure out how the code below works. I don't see how the add function ever gets called. I see them calling addTwo and addFive but those names are different than add. The result of this code being run is 9. Can someone please explain this to me.
function makeAddFunction(amount) {
function add(number) {
return number + amount;
}
return add;
}
var addTwo = makeAddFunction(2);
var addFive = makeAddFunction(5);
show(addTwo(1) + addFive(1));
In makeAddFunction, a function is created, called add. This function is returned.
makeAddFunction is called twice with 2 different parameters, and stored in two variables, addTwo and addFive.
Calling addTwo() and addFive() is calling the functions created by add(), with the "amounts" 2 and 5 respectively.
addTwo(1) + addFive(1) == (1 + 2) + (1 + 5) == 9
Sometimes these types of 'closures' are called Builders, or Factories. The makeAddFunction 'builds' a special version of add based on the parameter you pass to makeAddFunction.
The addTwo function would look like:
function addTwo(number) {
return number + 2;
}
The makeAddFunction create a closure that sets amount as whatever number you pass in and returns a function that will add that amount to whatever number you pass to the new function and return it.
My best advice is you try to learn a bit about Javascript closures. Really. I might not be the answer you are looking for, but it is the best you can do if you want to understand what's happening there.
Get yourself a copy of any good javascript book. Let me suggest 'Javascript - The Good Parts' by Douglas Crockford.
For some of us, Javascript closures were not something we grokked. I hope it's easier for you.
Anyway, makeAddFunctionis a function creator. It creates new functions which are tied to the parameter you passed to makeAddFunction. Therefore, the addTwo variable receives and stores a new function, which you can invoke later by appending parentheses to it, i.e. addTwo().
The parameter you pass to addTwo, i.e. 1on invokation addTwo(1) is passed to the add function, because addTwo is nothing more than an add function where the amount var has a fix value of 2.
var addTwo = makeAddFunction(2);
When you call makeAddFunction(2) initially, the amount var is within its function scope where add can see it. addTwo now is set to the add function that makeAddFunction(2) returned.
addTwo(1)
Remember addTwo is now set to what makeAddFunction(2) returned, which is the function add, and amount is set to 2 within makeAddFunction(2)'s scope. add just returns its argument (1), plus the amount (2) in makeAddFunction(2)'s scope.
The same goes for addFive(5).
Javascript Ninja or The Good Parts are good reads that explain closures in detail. I'd highly suggest picking up those.
Follow the SO Linked/Related Questions on the right. Anyway ..
This is explained the article, albeit with a lot of fluff. Anyway, with a bit of fluff-cutting here is a "annotated" version:
.. functions [do] not just package up [some code to run], but also an environment. [..] a function defined inside another function retains access [to lexical variables (like "amount")] that existed in [the outer function] at the point when [the inner function] was defined.
Thus, the [inner] add function in the above example, which is created when makeAddFunction is called, captures an environment [including the "amount" variable of the outer function]. It packages this environment, together with [the code to run], into a value [(which is a fancy way to say functions are just objects)], which is then returned from the outer function.
When this returned function ([which has been assigned to] addTwo and addFive) is called, [the called function has access to] the captured environment ([and the "amount" variable which still contains the value initially passed to makeAddFunction]). These two values ([which are currently named by] "amount" and "number") are then added, and the result is returned.
I am not found of the original usage of "value" and have edit those parts a good bit - in JavaScript, variables (not values) are bound in closures.
Javascript relies pretty heavily on higher-order functions. Functions can be returned, assigned to variables, and passed around as values. This comes in handy in a lot of situations, especially when dealing with evented programming (JS's direct lineage from the its most prolific implementation in the browser.)
http://en.wikipedia.org/wiki/Higher-order_function
What you are seeing is a function that creates a function. It could be considered a "factory" for a function with one preset argument.

Javascript/jQuery function arguments

Newbie jQuery / Javascript question here
I see functions written in the following fashion:
some_function = function(event) {
}
My question is: What is meant by that event argument? Is it optional? What if I want to have two additional parameters, X and Y, what would the signature look like? When I call the function now, I can just call it like some_function(); and it works fine (which leads me to believe that it's optional). However, how will that change when I have two additional arguments like X and Y? Can I just call it like some_function(myX, myY) ?
Thanks!
There are two ways to instantiate a function in JavaScript. They both look the same, but their meanings aren't quite the same.
What you've posted is a function instantiation as part of an expression in the language. In that form, the syntax is
function name ( p1, p2, ... ) { body }
The "name" and the parameters are optional; the keyword function and the parentheses are required. (There are some obscure issues with using a name in this case, in some browsers; it's getting to be less of a problem.)
The effect of that is to create a new function object. The reference to the object participates in the expression just like any other value (well, like any other reference to an object). Because it's a function, the reference can also be used to call the function and cause its code ("body") to execute, just like you'd expect. (It wouldn't be much of a function if you couldn't!)
The other way a function can be instantiated is with a function declaration statement, which looks, surprisingly, exactly the same (except that "name" is required). The difference involves where exactly in your code the keyword function appears:
If the keyword function is the first thing in a new statement, then you've got a function declaration and the "name" is required. The statement is not an expression statement in this case, and the only thing the statement does is instantiate the function and bind a reference to the function to "name" more or less as if "name" were a local variable (or global if in the global scope).
If the keyword function appears anywhere else in an expression (either an expression statement, or an expression buried inside some other context, like the top of a for or while loop statement), then it's a function instantiation expression.
Now, regardless of how a function is "born", once you've got a reference to the function you can call it and pass as many parameters as you like.
I don't know personally how the trend started, or whether it's even something that should be considered a trend, but it's fairly common to see local functions instantiated with code like this (and like what you posted):
var some_function = function( arg1, arg2 ) {
/* some code */
};
That's an example of a function instantiation in an expression. The net effect is that the symbol "some_function" is bound to the newly-created function. There are slight nitpicky differences, however, between the way that name is bound to the function from the (almost) equivalent function declaration:
function some_function( arg1, arg2 ) {
/* some code */
};
One simple reason that the second way (function declaration statement) is a little better is that the name of the function will show up in stack traces. Of course, one could achieve that with the redundant-looking:
var some_function = function some_function( arg1, arg2 ) {
/* some function */
};
I don't really know why you'd want to do that, but it'd work, except in some naughty environments.
That code snippet is a little vague, however I can answer, in general, your questions.
The event argument, in the code you provided, is just what that function will use to reference the first parameter that is passed to the function from whatever-other code calls it. For example, if you had code that called your some_function function, and passed it a string "hello world!", the call would look something like:
obj.some_function("hello world!")
Inside of the some_function function, the variable event would contain "hello world!". Also, you could change your some_function signature to be: some_function(blah) and it would be all the same, you would just use blah to reference the parameter instead of event. The variable name you choose for parameters is entirely up to you, though you want to make sure you don't use language-reserved names (like in, for, continue, break, etc)
Technically all parameters are optional for a JavaScript function, unless the internal code of the function enforces the parameters (i.e. it may return or throw an error if a parameter is missing.
#Pointy answered the other point I was going to make...that the code you provided is defining that function as an expression. I use that syntax when I'm creating a function that is an attribute of an object (which is why my above code has obj. at the beginning.

Weird issue with "this" losing its value in a validation function in aspect.around. Or, aspect.around is not working as expected

Note: please keep in mind that this is not a generic question on the use of this on javascript. This is about aspect.around malfunctioning (it's meant to set the scope for the call, and it doesn't). The question is: why is aspect.around malfunctioning? this question needs you to read carefully how to reproduce and do so with the fiddle provided!
I had to shred my app to pieces in order to make the problem fit in a fiddle.
So here it is:
http://jsfiddle.net/mercmobily/THtsv/1/
It's a simple form, with validation:
Type something in the textbox: the validation method of the widget will be called.
Then press the submit button: validation will fail, and aspect.around will be called to wrap something around the validation method.
At that point, try to type anything in the textbox again: It will come back with an error, as the validator will fail because of "this" being set to "window" instead of the widget.
So, once the aspect is added, the validator stops working. Basically, the value of "this" gets lost. Now:
aspect.around() is meant to run the new validator in the right scope (obviously) and it's failing to do so
I can "fix" this problem by changing the call to the validator into this: return originalValidator.call(this, value); However, it doesn't answer the question "Why is 'this' lost?"
If you backtrace the code, you will see that aspect.around() is doing what it normally does... but it must be doing something wrong
So, the question: why is dojo.around() malfunctioning, not setting this to the passed object's scope?
Merc.
It is not very easy to follow what exactly you're asking. From your jsFiddle, I see this comment so I'll attempt to answer the question you pose here:
// QUESTION: FIND OUT WHY WE NEED THIS "call"
return originalValidator(value);
// return originalValidator.call(this, value);
The answer to why you need the .call here in order to preserve the value of this is as I described below in the generic description of how this works when making a function call.
When you make an ordinary function call as in this statement:
return originalValidator(value);
The value of this is set back to window. That's how javascript works. If you want to preserve the current value of this in that function, you have to specify that you want a particular value of this set using .call() or .apply() or an obj.method() call. The value of this in an ordinary function call is NOT bound to the function. It's set by the caller and can be anything the caller wants. If you don't specify it, then javascript sets this to window and that is exactly what is happening in your code.
Here's the generic description of how the value of this is set and this generic description applies in your specific case.
The simple rule is that the value of this is reset on every single function call in javascript. If it's just a plain function call, then this is set to the global object (which is window in the browser environment). So any simple function call will always set this to window.
If you make a method call like obj.method(), then this will be set to point to the obj while in the method().
If you use func.apply(a, b) or func.call(a, b) then you can explicitly control what this is set to via the value of the first argument to .apply() or .call(). See this MDN doc here or here for more info on .call() and .apply().
this is the current context. By default it's the global object (or null in strict mode), when calling a function on an object (foo.bar()) it's set to that object. When using .call() or .apply() to call a function it's set to whatever first argument was passed to that function.
This means that you cannot assume that this is still the same when you go into another function - even if you define that function in a context where this is what you want.
The most common approach is adding var self = this; and then using self instead of this in the inner function - since self is a normal variable it will be in the function's closure and not be affected by this being bound to something else in the function.

Categories

Resources