Calling a function passed to a JQuery handler - javascript

function test() {
var str = 'adarsh';
// f1(); - This gives an error.
$('body').click(function f1() {
console.log(str);
});
}
test();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I want to know why the above snippet gives an error when I try to access f1() inside the function test.
What is the function f1 scoped to?
I know it is not the window because I cannot access window.f1 after executing the above snippet.
Note: I know I can declare function f1 first and then pass the reference to it in the click function. However I want to know what is the point of naming 'anonymous' functions in such contexts if we cannot access them anywhere through that name.

A function declaration will:
Create a variable with the same name as the function in the current scope.
A named function expression (which is what you have here) will:
Create a variable with the same name as the function inside the scope of that function (which is useful for calling itself recursively).
Evaluate as the function
So there are two ways you can access the function you created with the named function expression:
Put something on the left hand side of the expression. In this case you are already doing that by passing it to click(), so the click function can do something with it
Call it by name from inside itself
There are no further references to it in the scope of test.
However I want to know what is the point of naming 'anonymous' functions in such contexts if we cannot access them anywhere through that name.
As I said, the variable is useful for calling it recursively.
The name (which is different to the variable) is also useful as it shows up in debuggers. It is a lot easier to deal with a stacktrace consisting of a dozen useful names than one which is just a dozen repetitions of (anonymous function).

The BindingIdentifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the BindingIdentifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression. ## http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions-runtime-semantics-evaluation
In other words, when you have a function expression like function someName() {...} (not to confuse with a function declaration) the name is bound inside the function, not in the containing scope.
fun = function someName() {
alert(someName); // works
};
alert(typeof someName); // doesn't work
fun();
The purpose of giving names to function expressions is to have meaningful stack traces.

What is the function 'f1' scoped to?
It's not scoped to anything. The reference of the function is provided to the handler only, so there is nothing else defined which points to that function. If you want to define the function so that it can be called in multiple places you would need to change your logic to something like this:
function test() {
var str = 'adarsh';
$('body').click(function() { // < note the anonymous function here
f1(str);
});
}
function f1(str) {
console.log(str);
}
test();
f1('foo bar');

Calling a function passed to a JQuery handler
You can use jQuery._data() to access and call the event handler of click, f1, outside of .click()
function test() {
var str = "adarsh";
// f1(); - This gives an error.
$("body").click(function f1() {
console.log(str);
});
var ref = $._data(document.body, "events")["click"][0];
console.log(ref.handler, ref.handler.name);
ref.handler()
}
test();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>click</body>

Related

Javascript hoisting process with immediately invoked functions: Why doesn't this declared function run before function expression?

Code:
var funcExpression = function(){
alert("function expression");
}();
(function declarFunc(){
alert("declared func");
})();
The result is the function Expression is run first resulting in the alert "function expression" and the declared function is run second "declared func".
I know that during the hoisting process, declared functions are hoisted up entirely within their container and loaded into memory. Function expressions, however are not hoisted: they stay in the same place and are not loaded into memory until runtime(though the variable that points to the function expression is hoisted up and set to Undefined. (Please correct me if I have this concept wrong)
Since, the declared function is hoisted up above the function expression assignment, I would expect thus that the declared function is executed first: resulting in the alert "declared func" and then the function expression is executed afterwards: resulting in the second alert of "function expression".
However: it doesn't do what I expect. Thus, it seems like it has something to do with the immediate invocations of both the functions. Maybe the immediate invocations stay in the same order? Maybe after the hoisting process the code really looks like this:
var funcExpression = Undefined;
(function declarFunc(){
alert("declared func");
})
funcExpression = function(){
alert("function expression");
}();
(); // this executes declarFunc. Maybe declarFunc is hoisted up
// but the invoking part stays in the same place?
Solution after feedback and additional research
The answer is that BOTH of those functions are function expressions:
Code:
var funcExpression = function(){
alert("function expression");
}();
(function declarFunc(){
alert("declared func");
})();
so declareFunc() looks like a declared function, but since it is wrapped in parenthesis like that, it transforms it into a named function expression. The parenthesis following immediately evokes this function expression.
I was having trouble showing what the code looks like after the hoisting process because (function declarFunc(){...})() transforms into a named function expression due to those wrapping parenthesis. What this means is that outside of this named functions scope, we have no way to call it.
Example: If after these functions I did declarFunc() it will return with the error: ReferenceError: Can't find variable: declarFunc.
If we did want to make it possible to run this function expression then we would want to assign the function expression to a variable:
var foo = function declarFunc(){
alert("declared func");
};
Note: If we look at the console we will see that console.log(foo()) will return undefined, but the actions of the function will still take place. Just know that if no return statement is specified, then it implicitly returns undefined.
And now we can call on that function as many times as we would like with foo().

nodejs variable only in function and sub-functions

I'm trying to run the same function multiple times at once but if I create a local one with var variablename the sub-functions dont recognize it. And if I make it global, all instances of the Function will overwrite it.
function vladimir(){
var test="hello";
hanspeter();
}
function hanspeter(){
console.log(test);
}
console.log outputs undefined.
You're running into a scoping issue here.
When you declare methods without using var (function <function_name>() {}), those function declarations are moved to the top of the local scope (called function hoisting, if you want to look it up).
If you manually declare you functions, you have to wait until they are both declared before you can use them. This is because the first function won't know about any functions declared under it.
You've also got an issue where variables aren't being scoped. If you have a variable that you declare in one function, it isn't guaranteed to be there in another (since it is a different scope).
If you want to pass these variables around, the easiest way is to pass these into the function parameters, which will be reachable in your other function.
So in your simple example, you could get it to work like this:
var hanspeter = function (test) {
console.log(test);
}
var vladimir = function() {
hanspeter( "hello" );
}
Use function arguments:
function vladimir(){
var test="hello";
hanspeter(test);
}
function hanspeter(arg){
console.log(arg);
}
https://learn.jquery.com/javascript-101/functions/
JavaScript uses lexical scoping - it looks like you're expecting dynamic scoping. Essentially what this means is that a function has access to variables based on where it is declared, not where it is called. For example, the following would work:
function vladimir(){
var test="hello";
function hanspeter(){
console.log(test);
}
hanspeter();
}
Because test exists where hanspeter is declared. But in yours, test exists where hanspeter is called, which does not give it access.
You can also get variables by passing them:
function vladimir(){
var test="hello";
hanspeter(test);
}
function hanspeter(test2){
console.log(test2);
}
I called the argument to hanspeter test2 to show that it is the argument's name that matters, not the name of the variable being passed.

How do I read Javascript Closure Syntax?

Based on some code in a lecture by Doug Crockford, I've created this.
var isAlphaUser = (function() {
alert("Forming Alpha User List");
let AlphaUsers = {
1234: true,
5678: true
};
return function(id){
alert("Checking Alpha Users:",id);
return AlphaUsers[id];};
}());
alert("starting");
alert(isAlphaUser(1234));
alert(isAlphaUser(5678));
alert(isAlphaUser(3456));
which gives me this:
Forming Alpha User List
starting
Checking Alpha Users: 1234
true
Checking Alpha Users: 5678
true
Checking Alpha Users: 3456
undefined
Which is quite cool, as it does the expensive setup once only, and every further call is a cheap check.
However, I can't decipher the code that does this. Specifically, I can't understand why I need the "()" at the end of the function declaration.
Can somebody explain how this syntax is working?
() calls a function. function() { } defines a function. Appending () right after immediately calls it1, and the result (also an anonymous function) is assigned to isAlphaUser.
The function() { ... }() pattern is frequently used to isolate variables to an inner scope, so those variables don't become part of the global scope.
In this case, this is what happens:
An anonymous function is run, defining a variable AlphaUsers inside that scope.
That function returns another function that takes 1 parameter. This function is a closure to which the AlphaUsers variable becomes bound (in other words, available). This function checks if the parameter passed in is contained in AlphaUsers (actually, it returns the item at that index, which is just a boolean).
The return value is assigned to a variable isAlphaUser.
Since isAlphaUser is now a function, it can be called to see if the parameter is contained in the AlphaUsers variable, but no direct access to AlphaUsers is available in the global scope (it become a sort of private variable).
1 — Note: As cwolves mentioned in the comments, beware that while () appended directly after the } works in this case, it is only because in this case the function definition is a function expression. If function is the first word on the line, the line becomes a function declaration, and that is all that line can do, the function is not anonymous (it will require a name, otherwise it's a syntax error) and cannot be called immediately inline. See Function Declarations vs. Function Expressions for more info.
The () at the end of the code is separate from the closure issue. By wrapping your function in parens and adding the () at the end you are creating an anonymous function that is run immediately with whatever arguments you pass into ().
Specifically, I can't understand why I need the "()" at the end of the
function declaration.
It creates self-invoking function, in other words, the function is executed as soon as it is parsed.
It is basically same thing when you call a function by suffixing it with () like:
myfunc(); // call this func
The top-level anonymous function returns the function that the isAlphasUser varaible refers to.
You need to call the top-level function, to get the inner-function reference.
Think of it like this, the outer anonymous function is a function factory, i.e., it returns a function.
In order to use any function (even one that returns a function) you must call it.

Difference between "anonymous function" and "function literal" in JavaScript?

The book Learning JavaScript defines anonymous functions as follows...
Functions are objects. As such, you can create them - just like a String or Array or other type - by using a constructor and assigning the function to a variable. In the following code, a new function is created using the Function constructor, with the function body and argument passed in as arguments:
var sayHi = new Function("toWhom", "alert('Hi' + toWhom);");
This type of function is often referred to as an anonymous function because the function itself isn't directly declared or named.
Is this the correct definition of an "anonymous function" in JavaScript? If not, what is an anonymous function, and is there any difference between an anonymous function and a function literal?
Function expressions and function declarations
Since you are interested in functions, here is some important stuff to know.
var abc = function() { ... } is known as a function expression. The variable will be assigned that anonymous function at execution time, though its variable declaration will be hoisted to the top of the current execution context (scope).
However, a function expression can be given a name too, so that it can be called within its body to make it recursive. Keep in mind IE has some issues with this. When you assign it a name, it is most definitely not an anonymous function.
A function such as function abc() { ... } is known as a function declaration. Its definition is hoisted to the top of its scope. Its name is available within it and its parent's scope.
Further Reading.
Your Example
It is an anonymous function, but assigned to the variable sayHi.
As Šime Vidas mentions, a new Function object is instantiated with the new operator, and the arguments and function body are passed in as strings. The resulting object is assigned to sayHi.
The real world use of creating a function using this method is rare (though it may be just to help show that functions are objects). I also believe passing its arguments list and function body as a string will invoke an eval() type function, which is rarely good when a much better construct is available.
Also, functions created with Function do not form a closure.
I would only use this method if for some reason I needed to create a Function with its arguments and/or body only available to me as a string.
In the real world, you'd do...
var sayHi = function(toWhom) {
alert('Hi' + toWhom);
};
Also refer to comments by Felix and Šime for good discussion and further clarification.
I think a broader and more accepted definition of an anonymous function is a function that is created without a name.
An anonymous function is simply a function with no name.
function(a, b){
return a + b;
}
The above code would be useless as it has no name to which you could call it with. So they are usually assigned to a variable.
var func = function(a, b){
return a + b;
}
This is helpful because you can pass an anonymous function to another function or method without having to create the function before hand, as demonstrated below.
function bob(a){
alert(a());
}
bob(function(){
return 10*10;
})
This:
new Function("toWhom", "alert('Hi' + toWhom);")
and this:
function(toWhom) { alert('Hi' + toWhom); }
are two expressions that produce the same result - they return a new anonymous function object.
The second expression (and only the second expression) is called a function expression. You may also call it a function literal (although we could argue that a function declaration is also a function literal).
function foo(){
alert("i'm foo, nice to meet you!");
}
var bar = function(){
alert("I am an anonymous function assigned to the variable \"bar\"");
}

A simple question about Javascript functions, differences in invocation/definition

Can someone please explain the difference between the following function definitions?
var alertMessage = function alertMessage(message) {
alert(message);
}
var alertMessage = function(message) {
alert(message);
}
What are the implications of each? Thanks!
Both are function expressions, basically the difference is that the first is named, and the second one is anonymous.
For example:
var test = function test(message) {
alert(message);
};
var test1 = function(message) {
alert(message);
};
test.name; // "test"
test1.name // "" or "anonymous"
Note: The name property of function objects exist on some implementations, but it's non-standard.
Also, the name of function expressions it's useful for debugging, as you can inspect the call stack to see where you are.
This identifier is only accessible from inside the FunctionBody itself:
(function foo(){
typeof foo; // "function"
})();
typeof foo; // "undefined"
However there is a bug on the JScript implementation (in all versions of IE), which this name is leaked to its enclosing scope.
Both definitions are function expressions, as opposed to function declarations, or functions created by the Function constructor. They both assign a function to the variable alertMessage. The difference is that the first function is named, while the second is anonymous.
Named functions are usually used in function declarations, eg
function alertMessage(message) { ... }
In that case, the function declaration creates a variable in the current scope called alertMessage that references that function. Function declarations are hoisted to the top of the current scope, so you can call declared functions before they're defined in you js file.
A named function used in a function expression (such as the original question) does not create this variable, or get hoisted to the top of the execution scope, so by convention most function expressions are anonymous. The only benefits to naming a function expression are that the name variable is bound within the function (although as CMS mentions, this is implementation dependent) and the function name is output from the function's toString method. This can be useful during debugging (rather than having Firebug output (?) for a huge list of anonymous function calls).
Much more detail at MDC

Categories