I have no idea how to describe my question .
(function(fn){
var able=123;
function tmp(){
fn()
};
tmp();
})(function(){alert(able)});
This snippet throws a Reference Error :able is not defined' .
Would you please explain how javascript get variables to me ?
The scope of the "fn" function is not the same as the "parent" function, you should pass the "able" argument when you call the fn function, and then istantiate it in the fn function itself, like this:
(function(fn){
var able=123;
function tmp(){
fn(able)
};
tmp();
})(function(able){alert(able)});
Functions create lexical closures at the time of their creation. This means that when your alert function is created, the able variable does not exist. Wrapping the execution of fn in a lexical closure that does know about able at a later moment does not affect the already created lexical closure of fn.
If you come up with a question that better explains what you are trying to do, we can propose how to properly use closures to express that idea.
java script support in function local and global scoping.
in this case the "able" is local function scope you can't access outside the function.
If you use var the variable will be declared in the local scope. If u just declare the variable without a var, it will be declared in the global scope
Your code could be rewritten like this using named functions:
var func1 = function(fn) {
var able=123;
function tmp(){
fn()
};
tmp();
}
var func2 = function() {
alert(able)
}
func1(func2);
I believe this way it is clear that the variable 'able' is defined inside 'func1' (more precisely in its local scope) and you are trying to access it inside 'func2' which is outside the scope of 'func1' so it can not "see" into this scope.
More information about scoping in JavaScript can be found here: What is the scope of variables in JavaScript?
Related
function f1 () {
console.log('f1')
}
var s = 'f1'
runLocalFunctionByName(s)
Is this possible at all to write runLocalFunctionByName() or just call f1 without typing f1 in the source code, but using a variable holding its name? I mean without modifying f1 into a method, that answer is obvious: just make myobj.f1 = function or declare it globally like f1= function(). I am talking about normal local functions declared with function keyword only, not as vars, global vars or some other object property.
Not without the use of eval, which is evil (when used for this purpose for sure!).
Global functions could be called as attributes of the window object, but if they are in a local/closure scope that's not possible.
If you need to call functions by name, the only proper solution is storing them as attributes on an object, and then using obj[s]() for calling them.
One way of doing this is by using the instantiating a Function object.
var runLocalFunctionByName = function(fName) {
return (new Function('','return '+fName+'();'))();
};
Calling runLocalFunctionByName with a name of a function will now return the output of the named function.
EDIT
In case of local functions, the scope has to be mentioned, so we can modify the code, such that:
var runLocalFunctionByName = function(fName, scope) {
return (new Function('','return '+(scope?scope:'this')+'.'+fName+'();'))();
};
You can't access a local function outside its scope until unless you assign it to a variable having an accessible scope. MDN: A function defined by a function expression inherits the current scope. That is, the function forms a closure. On the other hand, a function defined by a Function constructor does not inherit any scope other than the global scope (which all functions inherit)
I have a function which allows user to pass a function.
function withPredicate(func){
//...
}
Inside my function, I need to detect whether the func that user pass in has closure or not.
It is not enough to get the function name and search it in window scope. User might pass in an anonymous function without closure like:
var func = function(x){return x;};
withPredicate(func);
EDIT:
I think I need to implement a function which takes a function as a argument and return bool.
function hasClosure(func){
//...
}
so several test cases are:
hasClosure(function(x){return x;}); //return false
var something = 30;
var func1 = function(x){return x.age < something;}
hasClosure(func1); //return false
var Closure = function(){
var something = 18;
var itself = function(x){
return x.age < something;
};
return itself;
};
var func2 = new Closure();
hasClosure(func2); //return true
The last one return true because func2 is not top-level function. When I see some free variable inside the function body like something, it may resolve to the variable defined in its closure other than the one defined in window.
Actually, what I need to do now is to do some manipulations based on the func that has been passed to my function. I can use JSLint to get the undeclared variable. But I also need to resolve these variables. It is acceptable that I can only resolve variables in global scope. But I still need a way to make sure that resolving these variables in global scope is correct. So I need to detect closures.
Is it possible to do that programmatically in javascript?
Alright this is really hacky and probably not worth the effort in actually writing unless your linting or something :)
Basically what you're going to have to do to determine if a function is a closure is call func.toString() which will give you the source of the function. You can then parse the function using some sort of parser which determines all the variables of the function func. You also need to determine and track how these variables are defined. In your criteria in op the criteria for it being a closure is having a variable that is defined outside of function scope and outside of window scope (thus closure scope). So if you can find any variables defined outside of these two scopes we've found a closure.
So heres the pseudocode of hasClosure(), have fun implementing.
func hasClosure(func)
source = func.toString(); //eg "function x(a) {return new Array(a)}"
variables = parseJSForVariables(source)//finds a and Array
for variable in variables:
if(variable not in window)
if(variable not defined in function)
return true //we got a closure
return false //not a closure
The correct answer highly depends on what a "closure" means in this context. The function from the question does not use the variables from the outer scope so, roughly, closure is not created for this function. But strictly speaking, closure is created for any function and binds definition context with the function. So whatever you want to detect, it requires a detailed specification.
But I can assume that the closure here means whether the function references variables declared in outer scope (just like https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures specifies). One of the static for analysis libraries can be used for this. For example, JSLint reports used but undeclared variables. Assuming that undeclared variables are just from the upper scope, this indicates that closure is created.
I read about JavaScript closures and I thought that I understood it, but apparently I didn't.
The success function is called when request is succeeded. This means that when the closure (function () {
return obj;
})(); is executed the scope, inside success function, is NOT function (evt) {...} anymore, so how it can still access obj?
How the closure work in this example
EDITED(there is var before obj)
function (evt) {
var obj = evt.data.obj,
$.ajax({
type: "POST",
url: url,
data: data,
success: function () {
var o = (function () {
return obj;
})();
}
});
}
In JS, scope is limited by function.
Everything inside a function to which a variable is scoped can access that variable — including other functions — unless there is another variable of the same name in a narrower scope.
That said, in this example there is no var keyword to localise the scope of the obj anyway, so it is a global. Removed after edit of question
One way to look at it is that closures have access to all scopes above themselves.
Another way would be to say that obj actually is accessible in scope of function function(evt), which is parent to the scope of function(), and therefore, obj is also accessible from function().
Either way, this is how JavaScript works: closure has access to everything that is accessible at the closure's point of definition.
A closure has access to all higher scopes, not only the "parent scope".
Since an obj variable isn't defined in the current scope, JavaScript goes up all the scopes the function has access to until it finds it.
It's like someone looking up a very weird ladder; one which can split to sub-ladders, but when you climb down these sub-ladders, you are still in the bigger ladder.
A closure has by design access to surrounding scope upon creation as it is created within the scope.
Any variables you access in the outer scope is accessed through a reference that will keep the variable alive after the scope within which it was created is destroyed.
That way when the closure executes, the variables it was referencing will still exist and only after the closure is disposed will the variables be released.
Each Function object has an Activation object that represents it's execution context.
Within a group of nested functions, A scope chain is formed starting from the inner most Activation object and ending with the Global object (Global Scope).
So unless there's a name clash between variables ,Each function has access to all of it's parent functions' local variables and parameters in addition to global variables.
Here's a lengthy but very useful explanation.
I see in a lot of scripts this pattern
(function(){})();
What is it and why use it?
It's used to force the creation of a local scope it avoid poluting the current (often global) scope with the declarations.
It could be rewritten like this if you want to avoid the anonymous function :
var scope = function() { /*...*/ };
scope();
But the anonymous function syntax have the advantage that the parent or global scope isn't even poluted by the name of the function.
(function() { /*...*/ })();
It's also a good way to implement information hiding in javascript as declarations (functions and variables) in this scope won't be visible from the outside. But they could still see each other and as javascript implement closures functions declared inside such a scope will have access to other declarations in the same scope.
That is defining a function with no name, and immediately calling it. Because Javascript functions act as closures -- a persistent scope -- this is a useful way to create a set of interconnected objects or functions.
An anonymous function is a function (or a subroutine) defined, and possibly called, without being bound to an identifier.
This is the basic syntax for creating a closure. More typically, it'd contain some code:
(function(){
//Your Code Here
})();
This is equivalent to
var some_function = function() {
//Your Code Here
};
some_function();
The biggest reason for doing this is cleanliness; any variables declared outside of any function are global; however, variables declared inside of this function are contained inside of this function and won't affect or interactive with any code outside of the function. It's good practice to wrap any kind of reusable plugin in a closure.
It's immediately executing anonymous function.
It's basically the same as:
var test = function(){};
test();
but does not require usage of additional variable.
you need to wrap it in additional parenthesis to get the function as a result of your expression - otherwise it's understood as function declaration, and you can't execute a declaration.
it's mostly used for scope protection - because JS has functional scope, every variable defined as var x; inside such function will be kept in it's function local scope.
all of this simply means 'immediately execute everything inside this function without polluting the global scope'.
it's also commonly used in well known patterns, such as module pattern and revealing module pattern. please see http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth for more detail.
It is called an immediate function or an anonymous closure and is the basis of the module pattern.
It is used to create a private local scope for code.
i have encountered the following curious piece of code:
function foo(){
works = {hello:"world"};
function bar(){
alert('does not work');
}
var notwork = {hello:"world"};
}
foo();
alert(works.hello);
alert(notwork.hello);
Can someone please explain to me why works work, and notwork doesn't work? Or point me out to a good resource that explains this in detail.
Thank you very much!
var notwork creates a local variable valid only for the runtime of the function.
works creates a global variable that is valid throughout the javascript runtime.
var declares a variable as "local" to the function it's defined in.
Without var, you works variable is global : it can be seen/accessed/used from anywhere.
With var, your notwork variable is local to the foo function : it cannot be seen/used from outside of that function.
For more informations, you can take a look at the documentation of the var statement on MDC, which states (quoting) :
The scope of a variable is the current
function or, for variables declared
outside a function, the current
application.
Using var outside a function is
optional; assigning a value to an
undeclared variable implicitly
declares it as a global variable.
However, it is recommended to always
use var, and it is necessary within
functions in the following situations:
If a variable in a scope containing the function (including the global
scope) has the same name.
If recursive or multiple functions use variables with the same name and
intend those variables to be local.
Failure to declare the variable in
these cases will very likely lead to
unexpected results.
You've missed out the var keyword so works is being defined on the global object.
You want
var works = ...