function foo() {
ui.login.setClose(function closer() {
ui.hideAll()
ui.main.show()
})
ui.ask.setClose(closer) // <-- closer is not defined
ui.adduser.setClose(closer)
}
I wonder why is this not working? Is not function keyword supposed to create a name visible anywhere within the current function (foo) body?
What you have there is called a named function expression. (Don't use them in IE8 or earlier, or some other quite old browsers.) It's different from a function declaration in several ways, one of which is that (on a correct implementation) the function's name is not added to the scope in which you create it.
In that example, you probably want a function declaration instead, either inside foo if you only want it accessible within foo:
function foo() {
function closer() {
ui.hideAll()
ui.main.show()
}
ui.login.setClose(closer);
ui.ask.setClose(closer);
ui.adduser.setClose(closer);
}
or outside foo if you want it accessible outside foo:
function closer() {
ui.hideAll()
ui.main.show()
}
function foo() {
ui.login.setClose(closer);
ui.ask.setClose(closer);
ui.adduser.setClose(closer);
}
Here's the rundown of the three main ways you create functions (other than the Function constructor, which should almost always be avoided):
Function Declaration
Looks like this:
// `foo` is in scope *and* ready to use here, even before the declaration
function foo() {
// `foo` is in scope and ready here too
}
// `foo` is in scope and ready here too
Characteristics:
Is not handled as part of the step-by-step code; instead, it's created before any step-by-step code in the scope is run. That means you could use foo above in code written above the declaration as well as below it.
Because of #1, a function declaration cannot be within control structures (like if, switch, for, etc.), since that's meaningless when the function will be created before the step-by-step code runs. (And it's important not to do it, as different browsers handle that invalid placement in different ways.)
Puts the name of the function in the scope where the function declaration appears.
The function has a real name, and that name is in scope within the function.
Named Function Expression
That looks exactly the same, except that it is written where an expression is expected, such as to the right of an = (e.g., an assignment) or : (in a property initializer) or as an argument to a function:
// `foo` is *not* in scope here
var x = function foo() {
// `foo` is in scope here, refers to the function
};
var obj = {
x: function foo() {
// `foo` is in scope here, refers to the function
}
};
bar(function foo() {
// `foo` is in scope here, refers to the function
});
// `foo` is *not* in scope here
Characteristics:
They are handled as part of the step-by-step code, just like any other expression.
They work correctly on modern browsers (including IE9 and higher), but there are bugs in IE8 and earlier, and some other quite old browsers had bugs as well (kangax wrote them up at the time).
Being expressions, they have a result: A function reference. (E.g., that's what gets assigned to x or passed to bar above.)
Their name is not added to the scope where they're defined.
The function has a real name, and that name is in scope within the function (e.g., for recursion).
Anonymous Function Expression:
The same as named function expressions, but, er, without names:
var x = function() {
// ...
};
var obj = {
x: function() {
// ...
}
};
bar(function() {
// ...
});
Characteristics:
They are handled as part of the step-by-step code, just like any other expression.
They result in a function reference (e.g., that's what gets assigned to x or passed to bar above).
The function doesn't have a name as of the current specification. However, the next specification, ES6, will have engines infer the name of the function where possible by looking at the expression. In the above, for instance, both of the ones that are assigned to x would have the name x; the one passed into bar would still be anonymous.
You would need to declare it as a function, not just a callback function.
Something like this:
function foo() {
function closer() {
ui.hideAll()
ui.main.show()
}
ui.login.setClose(closer);
ui.ask.setClose(closer) // <-- closer is not defined
ui.adduser.setClose(closer)
}
In this case
setClose()
is excepting a function as an argument which in your code is only defined inside () and thus it is not available outside of setclose(). This way of defining a function is typically used if the function is only needed in the argument. That is why in this case, in principle, you dont need to specify a name for it:
ui.login.setClose(function() { ui.hideAll(); ui.main.show(); });
However, in your case, you have to define the function closer() independently of the function setclose():
function closer() {
ui.hideAll();
ui.main.show();
}
function foo() {
ui.login.setClose(closer);
ui.ask.setClose(closer);
ui.adduser.setClose(closer);
}
You additionally missed some ; to end the line.
Related
We have two different way for doing function expression in JavaScript:
Named function expression (NFE):
var boo = function boo () {
alert(1);
};
Anonymous function expression:
var boo = function () {
alert(1);
};
And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?
In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)
Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.
(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)
One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:
var x = function example() {
console.log(typeof example); // "function"
};
x();
console.log(typeof example); // "undefined"
As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:
var obj = {
x: function() {
console.log(typeof x); // "undefined"
console.log(obj.x.name); // "x"
},
y: function y() {
console.log(typeof y); // "function"
console.log(obj.y.name); // "y"
}
};
obj.x();
obj.y();
The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.
The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:
var boo = function() { /*...*/ };
(or it could be let or const rather than var), or
var obj = {
boo: function() { /*...*/ }
};
or
doSomething({
boo: function() { /*...*/ }
});
(those last two are really the same thing), the resulting function will have a name (boo, in the examples).
There's an important, and intentional, exception: Assigning to a property on an existing object:
obj.boo = function() { /*...*/ }; // <== Does not get a name
This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.
Naming functions is useful if they need to reference themselves (e.g. for recursive calls). Indeed, if you are passing a literal function expression as an argument directly to another function, that function expression cannot directly reference itself in ES5 strict mode unless it is named.
For example, consider this code:
setTimeout(function sayMoo() {
alert('MOO');
setTimeout(sayMoo, 1000);
}, 1000);
It would be impossible to write this code quite this cleanly if the function expression passed to setTimeout were anonymous; we would need to assign it to a variable instead prior to the setTimeout call. This way, with a named function expression, is slightly shorter and neater.
It was historically possible to write code like this even using an anonymous function expression, by exploiting arguments.callee...
setTimeout(function () {
alert('MOO');
setTimeout(arguments.callee, 1000);
}, 1000);
... but arguments.callee is deprecated, and is outright forbidden in ES5 strict mode. Hence MDN advises:
Avoid using arguments.callee() by either giving function expressions a name or use a function declaration where a function must call itself.
(emphasis mine)
You should always use named function expressions, that's why:
You can use the name of that function when you need recursion.
Anonymous functions doesn't help when debugging as you can't see the name of the function that causes problems.
When you do not name a function, later on its harder to understand what it's doing. Giving it a name makes it easier to understand.
var foo = function bar() {
//some code...
};
foo();
bar(); // Error!
Here, for example, because the name bar is used within a function expression, it doesn't get declared in the outer scope. With named function expressions, the name of the function expression is enclosed within its own scope.
If a function is specified as a Function Expression, it can be given a name.
It will only be available inside the function (except IE8-).
var f = function sayHi(name) {
alert( sayHi ); // Inside the function you can see the function code
};
alert( sayHi ); // (Error: undefined variable 'sayHi')
This name is intended for a reliable recursive function call, even if it is written to another variable.
In addition, the NFE (Named Function Expression) name CAN be overwritten with the Object.defineProperty(...) method as follows:
var test = function sayHi(name) {
Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
alert( test.name ); // foo
};
test();
Note: that with the Function Declaration this can not be done. This "special" internal function name is specified only in the Function Expression syntax.
Using named function expressions is better, when you want to be able to reference the function in question without having to rely on deprecated features such as arguments.callee.
In the following example, why does the declaration of 'z' cause a syntax error?
(function(){
function x(){return 'this is x'};
y = function(){return 'this is y'};
//z : function(){return 'this is z'};
alert(x());
alert(y());
//alert(z());
})();
http://jsfiddle.net/VXPsd/2/
...why does the declaration of 'z' cause a syntax error?
Because you're using property initializer syntax outside of an object initializer.
This is an object initializer (the bit starting with { and ending with }) containing property initializer (the middle line):
var obj = {
propertyName: "property value"
};
So if you were declaring an object, you could use your z line (without the ;):
var obj = {
z: function() { return 'this is z'}
};
But where you have that in your code, you're not in an object initializer, you're in the body of a function. So you can't use that syntax.
It's worth noting that your x and y are quite different constructs from each other.
This:
function x(){return 'this is x'};
is a function declaration. Function declarations are processed before any step-by-step code in the containing function is run, and the function name is in scope from the top of the containing function. (Sometimes people call this "hoisting".)
This:
y = function(){return 'this is y'};
is a function expression. It's processed, like all expressions, where it's encountered in the step-by-step execution of the code in the containing function.
(The code as quoted falls prey to The Horror of Implicit Globals, btw: Since there's no var on y, and since you're not using strict mode, that line creates a global variable called y.)
What's the correct way to declare functions in a self executing function?
Neither form (the x or y form) is more correct than the other (leaving aside the implicit global thing). They each have uses, it depends on what you're doing. The y form has the issue that the function y refers to has no name (it's an anonymous function — the variable it's assigned to has a name, but the function doesn't). That can make debugging more difficult (looking at lists of breakpoints or the call stack), although modern debuggers are pretty good at showing you the variable name if the function doesn't have one, when they can.
Note that because they're not part of the step-by-step code, you cannot use a function declaration within a control structure:
function foo() {
if (condition) {
function bar() { /* ...do something... */ } // <==== WRONG
}
else {
function bar() { /* ...do something else... */ } // <==== WRONG
}
}
That's one of the reasons we have function expressions:
function foo() {
var bar;
if (condition) {
bar = function() { /* ...do something... */ }; // <==== Right
}
else {
bar = function() { /* ...do something else... */ }; // <==== Right
}
}
Note that some JavaScript engines tolerate the wrong syntax above, but the way that they tolerate it varies from engine to engine. Some engines convert the declarations into expressions for you. Others just always use the second declaration. Just don't do it. :-)
And finally: There's also something called a named function expression:
var x = function foo() { /* ... */ };
The function has a name (foo), and the variable referring to it has a name (x). It's an expression because it's used as a right-hand value (the right-hand side of an =, the : in an initializer, if you were passing it into a function as an argument, etc.) Sadly, various JavaScript engines have been known to get NFEs (as they're called) wrong in various different ways, although I think in today's world, it's really just IE8 and earlier, which create two different functions at different times.
The variableName : value syntax can only be used in the context of an object. For example:
var obj = {
z: function(){return 'this is z'};
};
In which case running obj.z() will return This is an object.
In your case you are just in the context of a function, not declaring an object. Which means you have to use the syntax you used with x or y.
The colon notation only works inside of object syntax.
For example
var theObj = {one : 'one', two : 'two'};
In order to add to the object you should use dot notation:
theObj.three = 'three';
As an executed Anonymous Function (with hiding);
var objOuter = (function(){ // Anonymous Function
var funcPrivate = function() {
// private function contents
};
var funcPublic = function() {
// private function contents
};
return { // JavaScript Object
funcName : funcPublic // provides public access to funcPublic
};
})();
//objOuter.funcPrivate(); // Failure, private.
//objOuter.funcPublic(); // Failure, internal name for public function.
objOuter.funcName(); // Executes funcPublic in objOuter's scope.
As part of a JavaScript object definition (everything is public):
var objOuter = { // JavaScript Object
funcName : function() {
// function contents
}
};
objOuter.funcName(); // Executes funcName
The Anonymous Function is executed JavaScript code, but the inside of the {} for the JavaScript object definition is a different kind of syntax that pairs keys and values.
Inside the JavaScript object you assign the value function() to key funcName. When you reference that key and execute it by passing it an argument list (), the function executes.
In the Anonymous Function (also called the Revealing Module Pattern), you are defining private functions inside the scope of the module and then passing references to those functions to the calling code as part of the returned JavaScript object.
While reading about IronJS, I can across the article here http://ironjs.wordpress.com/
In it is the following:
*Context sensitive function keyword
In case you didn’t know, these two functions are not identical:
(function bar() { })
function foo() { }
Finding out the difference I’ll leave as an exercise to the reader.
Can some explain the difference here?
function foo() { }
Creates a function
(function foo(){ })
Returns a function object. You can also use:
(function foo(){ })(bar)
And make an anonymous function. (Note that the (bar) means that within that function this refers to the bar instance.)
Check out this other SO post for more information.
I am guessing the difference is that the first one is not visible to the global scope and the latter is visible globally.
To expand on #Amir's answer:
js>(function bar() {})(3)
js>bar
console:1 ReferenceError: bar is not defined
js>function foo() {}
js>foo
function foo() {
}
(code executed in jsdb)
These are named functions, and if you don't put parentheses around the function definition, they become part of the local scope. function foo() {} becomes available for use later, but bar does not.
As a third example:
var x = function baz() {};
If you run this:
js>var x = function baz() {}
js>baz
console:1 ReferenceError: baz is not defined
You'll note that it's the similar case as (function baz(){})(3).
The case of
function foo() {}
is special, the Javascript interpreter sees that form and says, "Oh, you're trying to define a function named "foo" in the local scope."
As for why a named function is useful even if it doesn't get defined in the local scope -- the named function is visible from the scope of the function itself:
js>var x = function fact(n) { return n*((n < 2) ? 1 : fact(n-1)); }
js>x(3)
6
js>fact
console:1 ReferenceError: fact is not defined
Here we have a factorial function named "fact", but the name "fact" is only visible inside the scope of the function itself.
The first function is a named anonymous function (yeah). The expression evaluates to a Function. The second one defines a named function and returns undefined.
As far as I know, function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript. So adding function foo() { bbb(); } should either overwrite the foo variable, or ignore the second definition - that's not the point. The point is that there should be one variable foo.
So, in this example the me variable should not be correctly resolved from inside the methods and it is not in Explorer 8 :-). I came to this example by trying to wrap them into another closure where (var) me would be, but I was surprised that it's not necessary:
var foo = {
bar1 : function me() {
var index = 1;
alert(me);
},
bar2 : function me() {
var index = 2;
alert(me);
}
};
foo.bar1(); // Shows the first one
foo.bar2(); // Shows the second one
Demo: http://jsfiddle.net/W5dqy/5/
AFAIK function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript.
Not quite; they're similar, but also quite different. JavaScript has two different but related things: Function declarations (your first example there), and function expressions (your second, which you then assign to a variable). They happen at different times in the parsing cycle and have different effects.
This is a function declaration:
function foo() {
// ...
}
Function declarations are processed upon entry into the enclosing scope, before any step-by-step code is executed.
This is a function expression (specifically, an anonymous one):
var foo = function() {
// ...
};
Function expressions are processed as part of the step-by-step code, at the point where they appear (just like any other expression).
Your quoted code is using a named function expression, which look like this:
var x = function foo() {
// ...
};
(In your case it's within an object literal, so it's on the right-hand side of an : instead of an =, but it's still a named function expression.)
That's perfectly valid, ignoring implementation bugs (more in a moment). It creates a function with the name foo, doesn't put foo in the enclosing scope, and then assigns that function to the x variable (all of this happening when the expression is encountered in the step-by-step code). When I say it doesn't put foo in the enclosing scope, I mean exactly that:
var x = function foo() {
alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo); // alerts "undefined" (in compliant implementations)
Note how that's different from the way function declarations work (where the function's name is added to the enclosing scope).
Named function expressions work on compliant implementations. Historically, there were bugs in implementations (early Safari, IE8 and earlier). Modern implementations get them right, including IE9 and up. (More here: Double take and here: Named function expressions demystified.)
So, in this example the me variable shoudl not be corectly resolved from inside the methods
Actually, it should be. A function's true name (the symbol between function and the opening parenthesis) is always in-scope within the function (whether the function is from a declaration or a named function expression).
NOTE: The below was written in 2011. With the advances in JavaScript since, I no longer feel the need to do things like the below unless I know I'm going to be dealing with IE8 (which is very rare these days).
Because of implementation bugs, I used to avoid named function expressions. You can do that in your example by just removing the me names, but I prefer named functions, and so for what it's worth, here's how I used to write your object:
var foo = (function(){
var publicSymbols = {};
publicSymbols.bar1 = bar1_me;
function bar1_me() {
var index = 1;
alert(bar1_me);
}
publicSymbols.bar2 = bar2_me;
function bar2_me() {
var index = 2;
alert(bar2_me);
}
return publicSymbols;
})();
(Except I'd probably use a shorter name than publicSymbols.)
Here's how that gets processed:
An anonymous enclosing function is created when the var foo = ... line is encountered in the step-by-step code, and then it is called (because I have the () at the very end).
Upon entry into the execution context created by that anonymous function, the bar1_me and bar2_me function declarations are processed and those symbols are added to the scope inside that anonymous function (technically, to the variable object for the execution context).
The publicSymbols symbol is added to the scope inside the anonymous function. (More: Poor misunderstood var)
Step-by-step code begins by assigning {} to publicSymbols.
Step-by-step code continues with publicSymbols.bar1 = bar1_me; and publicSymbols.bar2 = bar2_me;, and finally return publicSymbols;
The anonymous function's result is assigned to foo.
These days, though, unless I'm writing code I know needs to support IE8 (sadly, as I write this in November 2015 it still has significant global market share, but happily that share is plummetting), I don't worry about it. All modern JavaScript engines understand them just fine.
You can also write that like this:
var foo = (function(){
return {
bar1: bar1_me,
bar2: bar2_me
};
function bar1_me() {
var index = 1;
alert(bar1_me);
}
function bar2_me() {
var index = 2;
alert(bar2_me);
}
})();
...since those are function declarations, and thus are hoisted. I don't usually do it like that, as I find it easier to do maintenance on large structures if I do the declaration and the assignment to the property next to each other (or, if not writing for IE8, on the same line).
Both me lookups, are only visible/available inside the function expression.
Infact those two are named function expressions, and the ECMAscript specification tells us, that the name of an expression is not exposed to the such called Variable object.
Well I tried to put that only in a few words, but while trying to find the right words, this ends up in pretty deep chain of ECMAscript behavior. So, function expression are not stored in a Variable / Activation Object. (Would lead to the question, who those guys are...).
Short: Every time a function is called, a new Context is created. There is some "blackmagic" kind of guy that is called, Activation object which stores some stuff. For instance, the
arguments of the function
the [[Scope]]
any variables created by var
For instance:
function foo(test, bar) {
var hello = "world";
function visible() {
}
(function ghost() {
}());
}
The Activation Object for foo would look like:
arguments: test, bar
variables: hello (string), visible (function)
[[Scope]]: (possible parent function-context), Global Object
ghost is not stored in the AO! it would just be accesssible under that name within the function itself. While visible() is a function declaration (or function statement) it is stored in the AO. This is because, a function declaration is evaluated when parsing and function expression is evaluated at runtime.
What happens here is that function() has many different meanings and uses.
When I say
bar1 : function me() {
}
then that's 100% equivalent to
bar1 : function() {
}
i.e. the name doesn't matter when you use function to assign the variable bar1. Inside, me is assigned but as soon as the function definition is left (when you assign bar2), me is created again as a local variable for the function definition that is stored in bar2.
I'm a little confused.
Everywhere i look, people say that i should use self invoking functions for scoping reasons, to avoid global namespace pollution.
But in this aspect, self invoking function seems to act identically to regular function, as in this example:
function xx(){
var x="variable";
//logs into console
console.log(x);
}
xx();
//logs undefined
console.log(x);
So, only real difference with regular function and self invoking is "self invoking" part, meaning i just don't have to run function manually after declaration?
A “self-invoking function” is a name for a common JavaScript idiom. It’s not actually a type of function; it’s the immediate execution of a function. You can call it an IIFE for “immediately invoked function expression” instead if that helps.
(function () { // Anonymous function expression
// IIFE!
})(); // Invocation happens here with the ()!
var f = (function () { // Still anonymous
// Almost immediately invoked function expression!
});
f(); // Invocation happens here!
var f = (function f() { // Not anonymous – now called “f”
// Almost immediately invoked function expression!
});
f(); // Invocation happens here!
function f() { // Not anonymous
// Almost immediately invoked function *declaration* – not an expression!
}
f(); // Invocation happens here!
Self-invoking functions are normal functions, but don't have a name. That makes them impossible to call except immediately after being declared, which effectively makes them a one-time-use function that is forever hidden from other code.
As you point out, the form
function foo() {
console.log("foo");
}
foo()
and
(function () {
console.log("foo");
})()
behave identically.
However, the first form with function foo() {... creates a named function that lives in that scope until the scope is destroyed. For the global scope, that will never happen, leaving foo a valid and callable identifier for any other code in your application.
That means that at any time, anybody else can do
foo()
and either initialize your module again or, potentially, obtain a handle to a new copy of the module.
At best, this can cause confusion and duplicate state. At worst, depending on how your IIFE is structured, they may be able to dig into hidden state and start manipulating it in ways you don't expect.
Writing a function that is both anonymous and immediately invoked prevents anyone from ever invoking it again, making it a clean and safe way to create and use a completely hidden scope. That's why you see it used so often to provide private state or construct a module.
They must have confused a IIFE with "self-invoking function".
Here's something Ben Alman wrote:
What’s wrong with “Self-executing anonymous function?”
You’ve already seen it mentioned a few times, but in case it wasn’t clear, I’m proposing the term “Immediately-Invoked Function Expression”, and “IIFE” if you like acronyms. The pronunciation “iffy” was suggested to me, and I like it, so let’s go with that.
What is an Immediately-Invoked Function Expression? It’s a function expression that gets invoked immediately. Just like the name would lead you to believe.
I’d like to see JavaScript community members adopt the term “Immediately-Invoked Function Expression” and “IIFE” in their articles and presentations, because I feel it makes understanding this concept a little easier, and because the term “self-executing anonymous function” isn’t really even accurate:
// This is a self-executing function. It's a function that executes (or
// invokes) itself, recursively:
function foo() { foo(); }
// This is a self-executing anonymous function. Because it has no
// identifier, it must use the the `arguments.callee` property (which
// specifies the currently executing function) to execute itself.
var foo = function() { arguments.callee(); };
// This *might* be a self-executing anonymous function, but only while the
// `foo` identifier actually references it. If you were to change `foo` to
// something else, you'd have a "used-to-self-execute" anonymous function.
var foo = function() { foo(); };
// Some people call this a "self-executing anonymous function" even though
// it's not self-executing, because it doesn't invoke itself. It is
// immediately invoked, however.
(function(){ /* code */ }());
// Adding an identifier to a function expression (thus creating a named
// function expression) can be extremely helpful when debugging. Once named,
// however, the function is no longer anonymous.
(function foo(){ /* code */ }());
// IIFEs can also be self-executing, although this is, perhaps, not the most
// useful pattern.
(function(){ arguments.callee(); }());
(function foo(){ foo(); }());
// One last thing to note: this will cause an error in BlackBerry 5, because
// inside a named function expression, that name is undefined. Awesome, huh?
(function foo(){ foo(); }());
Source : http://benalman.com/news/2010/11/immediately-invoked-function-expression/
// defined at `window`
function xx() {
var x = "variable";
//logs into console
console.log(x);
}
xx();
// not defined at `window`
(function yy() {
var y = "variable";
//logs into console
console.log("y:",y);
// `window["yy"]` : `undefined`
console.log("yy:", yy, "window['yy']:?", window["yy"]);
}());
console.log("xx", xx, window["xx"]);
try {
console.log("yy:", yy, window["yy"]);
} catch (e) {
console.log("yy:", e)
}
try {
console.log("x:", x);
} catch (e) {
console.log("x:", e)
}