Reputation: 2737
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.
Upvotes: 3
Views: 57
Reputation: 1
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>
Upvotes: 0
Reputation: 943108
A function declaration will:
A named function expression (which is what you have here) will:
So there are two ways you can access the function you created with the named function expression:
click()
, so the click
function can do something with itThere 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)
.
Upvotes: 5
Reputation: 214949
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.
Upvotes: 4
Reputation: 337560
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');
Upvotes: 3