If I have a function inside another function but the inner function doesn't use the outer function's variables, will the inner function still be a closure?
function someFunc(){
return function(){
\\do some more stuff
}
}
Whenever you see the function keyword within another function, the inner function has access to variables in the outer function.
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + tmp);
}
bar(5);
}
foo(2);
This will always alert 10, because bar can access the x which was defined as an argument to foo, and it can also access tmp from foo.
For info about closures, refer: http://javascriptissexy.com/understand-javascript-closures-with-ease/
Related
I want to understand how nested functions work for example
function outer(){
console.log("Hello from outer function")
function inner(){
console.log("Hello from inner function")
}
}
I want to understand what happens when i call outer(), how can i call the inner function, what is the execution context for inner function,
As you have not called inner() anywhere in the outer() function so that is why inner() is not getting called by default.
JavaScript will automatically allocate memory when values are initially declared. There is a link where you can read about memory management in JS
You cannot call inner() from outside. Once outer() finishes executing inner() will be garbage collected, since there is no other references to it.
function outer(){
console.log("Hello from outer function")
inner();
function inner(){
console.log("Hello from inner function")
}
}
outer();
Using a closure way:
function outer() {
var name = 'StackOverflow';
function inner() {
console.log("I am in Inner function at " + name);
}
return inner;
}
var outerfunction = outer();
outerfunction();
But if you see we are calling inner() in the outer function indirectly.
I think you mean this syntax:
functionName()();
this is syntax happen when a function return another function. like the code blow:
function f1(value1) {
return function f2(value2) {
return value1 + value2;
};
}
Mozilla's Developer Resource shows two contradicting explanation regarding the function scope.
Here
indicates that even though a "variable is defined in the same scope as the function calls", the code will throw an error because "it is not defined inside the function definitions".
Example)
function myBigFunction() {
var myValue;
subFunction1();
}
function subFunction1() {
console.log(myValue);
} //this will show a reference error
However, here indicates that a "function defined inside another function can also access all variables defined in its parent function and any other variable to which the parent function has access".
Example)
function getScore() {
var num1 = 2,
num2 = 3;
function add() {
return name + ' scored ' + (num1 + num2);
}
return add();
} //this is ok
In your first example
function myBigFunction() {
var myValue;
subFunction1();
}
function subFunction1() {
console.log(myValue);
} //this will show a reference error
here myValue is included in a function myBigFunction() so it has a block scope.
Block scope means any code within that block (here function defines the block) can use that variable if function contain another function(function definition) and inner function using that variable then it will be passed in a closure to inner function. 2nd scenario exactly same what I explained here.
function getScore() {
var num1 = 2,
num2 = 3;
function add() {
return name + ' scored ' + (num1 + num2);
}
return add();
} //this is ok
In above example num1 and num2 are declared in function getScore(), and it has inner function add() since add function using num1 and num2 it will be passed as closure to add() function and there won't be any error while accessing those variables.
but in first example the variable is accessed out of scope and as the variable accessed outside of that function it won't be accessible and it will throw reference error.
I hope the explanation clear your understanding. to understand it thoroughly go through JavaScript scope and closure concept.
The reason why the first example fails and the second 'works' has to do with scope and closure. You can think of a function's 'curly braces' as the enclosure around its scope - or sphere of influence.
The first example fails because myBigFunction()'s variable is not accessible to subFunction1()'s scope. myBigFunction() also doesn't wrap subFunction1() which would provide a closure. Check out closures here.
However, add() is declared within the scope of the getScore() function. getScore() 'wraps' add() - providing a closure so that add() has access to variables within getScore()'s scope.
Use the this keyword to get parent variable i.e.
var bar = function () {
this.foo = "example";//the only catch is you have to have the this key word when defining the term.
var subfunction = function () {
this.foo = "This an example!";
}
}
(Hope this helps!)
my question regards the following example:
function inner(x){
return x;
}
function outer(fn){
var x = 'I just made a closure!!!'
return fn.bind(this, x)
}
var y = outer(inner)
y()
when y() is invoked, does it has a closure over x because of bind? I'm confused because it does has access to an inner variable of the function outer, but it's nonetheless declared outside the scope of outer
when y() is invoked, does it has a closure over x because of bind?
No, calling bind on a function returns a bound function. This bound function might however closure the function and the arguments, but that depends on the implementation. An implementation with a closure would look like:
Function.prototype.bind = function(context, ...args) {
const bound = this;
return function(...args2) { // the closure
bound.call(context, ...args, ...args2);
};
};
when y() is invoked, does it has a closure over x because of bind?
Not quite.
The value of x is passed as an argument to bind.
Consider this rough approximation of what an implementation of the bind function might look like:
function bind(this_value, first_argument_value) {
return function () {
// Call the original function with arguments and context
}
}
It is first_argument_value that is closed over, not x.
How can I get access to my y() function?
function x() {
function y() {
return 1;
}
}
Is it possible at all?
It is scoped to x, kind of like:
function x() {
var y;
}
So, yes, from within x, and no otherwise.
If you wanted it to be, you could create it as a property on x:
var x = (function () {
function x() {
…
}
function y() {
…
}
x.y = y;
return x;
})();
You mean access it from outside the function x?
That's not possible, the function y doesn't exist when x is not running. It's declared locally inside x so it's only accessible inside x.
To make it accessible outside x you need to expose a reference to it outside the function. If you expose a reference to it, it survives after the function ends. For example:
function x() {
function y() {
return 1;
}
return y;
}
// get the reference to y
var f = x();
// call y
f();
You can get access to your y function inside of the scope of the x function Only.
But you can get access to the y function if you return it from your x function or assign it to a global variable or to the variable that is in scope outside of your x function. This is also know is closure, your y function will keep the reference in memory to the scope it was created in if you pass it around.
function x() {
var anotherNum= 2;
function y() {
return 1 + anotherNum;
}
return y;
}
Now you can get the y function along with the scope it was created in. Notice that it will use anotherNum in the computation as it was created in the x function.
var yFunc = x();
console.log(yFunc()) // will print 3
One way is to return it out of the scope
function x() {
function y() {
return 1;
}
return {
y:y
};
}
Whenever you call x(), it returns an object with the function y as a member
var a = x();
a.y(); //this returns 1
This is similar to the revealing module pattern described here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures
Also good to read up on closures:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FClosures
Is it possible to do what I want? the changeEl() function is also in fadeGall()
function initOpen(){
$('ul.piple-holder > li > a, ul.work-holder > li > a').each(function(){
var _box = $(this);
_box.click(function(){
//SOME CODE HERE TO RUN changeEl(0); on each _hold
//element from fadeGall()
});
});
}
function fadeGall(){
var _hold = $('div.work-info');
_hold.each(function(){
var _hold = $(this);
function changeEl(_ind){
return;
}
});
}
No idea what you're trying to do, but if you are asking if it's okay to define a function inside of another one, sure, it is. Just be aware that the nested function won't be callable outside of the function it was defined in.
You can nest a function within a function. The nested (inner) function is private to its containing (outer) function. It also forms a closure.
A closure is an expression (typically
a function) that can have free
variables together with an environment
that binds those variables (that
"closes" the expression).
reference
Since a nested function is a closure, this means that a nested function can "inherit" the arguments and variables of its containing function. In other words, the inner function contains the scope of the outer function.
To summarize:
The inner function can be accessed only from statements in the outer function.
The inner function forms a closure: the inner function can use the arguments and variables of the outer function, while the outer function cannot use the arguments and variables of the inner function.
The following example shows nested functions:
function addSquares(a,b) {
function square(x) {
return x * x;
}
return square(a) + square(b);
}
a = addSquares(2,3); // returns 13
b = addSquares(3,4); // returns 25
c = addSquares(4,5); // returns 41
Since the inner function forms a closure, you can call the outer function and specify arguments for both the outer and inner function:
function outside(x) {
function inside(y) {
return x + y;
}
return inside;
}
fn_inside = outside(3);
result = fn_inside(5); // returns 8
result1 = outside(3)(5); // returns 8