I know what an Immediately-Invoked Function Expression is. I know the difference between this
let x = function()
{
}
and this
let x = (function()
{
})()
but what about this
let x = (function()
{
})
do the parenthesis here have any significance alone? I've seen it in several places before.
I thought this was an example but it might not be one X)
edit: Those weren't really intended to be code snippets, anyhow assuming they're snippets, it turns out there's big difference between the case where they are function declarations and function expressions. I didn't expect this. Sorry for the context change and thanks for all the care!
Answer to the edited question:
but what about this
let x = (function()
{
})
There is no purpose served by those () at all. That's exactly the same as:
let x = function()
{
}
Answer to question embedded in comments:
In a comment you've said you actually were wondering about this:
let foo = () => ({ bar: { foo: 1, bar: 2, } });
The () are necessary because that's an arrow function with a concise body returning the result of an object initializer. But if there's a { immediately after the =>, the { would be the opening of a block (verbose) body instead (not the beginning of an object initializer). That's why the () are necessary around the expression body of the concise arrow, to disambiguate the {.
Note that the () are not around the function; just its body.
You can write it the way you did:
let foo = () => ({ bar: { foo: 1, bar: 2, } });
or with {} and return:
let foo = () => { return { bar: { foo: 1, bar: 2, } } };
but not:
let foo = () => { bar: { foo: 1, bar: 2, } }; // Wrong
because the { would be read as the beginning of a block body.
Answer to original question:
I'm going to assume these have names, as otherwise your first example is a syntax error.
but what about this
(function()
{
})
That would be a function expression that isn't immediateley invoked. Unlike your first example, it's evaluated when the step-by-step execution reaches it, instead of when the context it's in is initially created.
Unless something is using the result of that expression, it's a no-op (something that does nothing), since nothing in the expression runs it.
If the result of the expression is being used (it's the right-hand side of an assignment, it's being passed into a function as an argument, etc.), the () around it are unnecessary with a function expression. (That isn't always the case with an arrow function.)
Given the original question:
All else being equal (and it probably isn't because you omitted the context):
This is a syntax error. It starts off as a function declaration and then doesn't meet the syntax requirements.
This is an immediately invoked function expression.
The parenthesis make this a function expression (just like in example 2). It isn't invoked (the () are missing at the end). It isn't assigned anywhere. It does nothing.
But now you've rewritten the question and completely changed the meaning.
Example 3 and Example 1 are now the same.
Putting ( and ) around an expression does nothing except override operator precedence … and there are no operators inside them.
There's no difference between (function() {}) and function() {}.
This lines are also the same :
var test1 = (function() {});
var test2 = function() {};
BUT, if you only write this :
function() {};
You'll get a syntax error. If you don't want a syntax error you have to write this :
(function() {});
But this line is useless and do nothing at all. Because the defined function is never called and no one can access it.
Enclosing a function in parentheses in this way lets you package it for use in another variable or function.
For example, you could use this (somewhat redundantly) to set a variable to a function.
var foo = (function bar() { /* code */ });
foo(); // calls code in bar()
This is also a way to package a callback function, e.g.
asyncFunction((function callback() { /* code */ });
You wouldn't want to use this type of declaration on its own because it becomes hidden to the rest of your code as in the below example.
function foo() { /* code */ };
(function bar() { /* code */ });
foo(); // runs foo code
bar(); // ERROR - bar() undefined in this scope
A similar syntax is used with a trailing parentheses in an "Immediately-Invoked Function Expression". This passes a variable into your function and runs it inline.
(function foo(a) { console.log(a) })("Hello World!");
// Prints "Hello World"
TL;DR - Use it as a way to write a named function inline and package it into another function or variable or, with trailing parentheses, to call your function immediately with a specified input.
Related
While this code is fine:
var x = function() { };
This code is not:
function() { };
The top example creates an anonymous function and assigns it to x. The bottom example is a statement, where a function name is required, so it is a syntax error.
Now, it may seem pointless to define an anonymous function and not assign it anywhere, but here's an example that confronts the behavior:
var x = eval('function() { }');
Which should behave just like the first example, but is a syntax error.
Deep in the app I'm working on, we come to this issue. I want function() { } to be an expression.
A short explanation why is that this is a native OSX app calling javascript into a WebView. We have an evaluateJavascript function which the native layer can use to call arbitrary javascript. evaluateJavascript wraps the given code with try/catch for error-handling, because it's the only way to get detailed error information. So if you call myCallback = evaluateJavascript("function() { }"), we generate a function with the following body:
try {
return eval('function() { }');
} catch(e) {
// ....
}
And return the result.
When possible, don't use eval. Another option to find errors is if you listen for errors on the window (or equivalent) object and import the scripts as <script>s which are added and removed immediately.
Doing anything on the same line before function will cause function to be an expression
All of the following are valid (although useless)
0, function () {};
(function() {});
+function () {};
-function () {};
!function () {};
// etc
Function expressions like this are usually done for IIFEs, i.e.
(function (foo) {
console.log(foo);
}('bar'));
// "bar" logged
But you can apply the style to your eval-ing. Either parenthesis or the comma operator should work for you
var code = 'function () {}';
var foo = eval('0, ' + code);
foo; // function () {}
Can't you do
x = eval('y = function() {}')
?
You say var x = eval('function() { }'); should behave just like the first example. Why do you think so? Your eval argument
function() { }
is a statement and invalid as you point out above. You could make it an expression like this:
var x = eval('(function() { })');
Attempt/Approach- 1 : Below should work
var scope = {};
eval('scope.x = function() { return "Hello World"; }');
console.log(scope.x());
Output
Hello World
[Finished in 0.3s]
** Approach - 2 **
After reading link on IIFE insuggested in comments of above question, I tried below - and it seems to work as well.
var x = eval('(function() { return "Hello World"; })');
console.log(x());
However, I realized that with IIFE, we need to have code like (function(){})() - note that trailing (). However, in the Approach-2 code - I did not have the trailing (). Then, I looked up the eval documentation, and from it I came to know the following (which explains why Approach-2 works):
eval as a string defining function requires "(" and ")" as prefix and
suffix
This question already has answers here:
Why should I use a semicolon after every function in javascript?
(9 answers)
Closed 7 years ago.
Ok, I asked a question, and someone smarter than me said the question was an "exact" duplicate of mine. Well it wasn't, and the answers did not answer the guy's question. He wanted to know how to call another procedure, I want to know how to call a function within the class. That being said when I was trying to find an answer to my problem and I was looking at answers to similar questions sometimes function were terminated with }; other times with } and still other times with }, (this one I think I understand). However I cannot see in rhyme or reason why or when the brace with a semicolon is to be used and when just the brace should be used:
Here was the first answer
var ExampleClass = function(){
this._m_a = null;
};
ExampleClass.prototype.get_m_a = function(){
return this._m_a;
};
ExampleClass.prototype.set_m_a = function(value){
this._m_a = value;
};
notice this answer doesn't even address the calling of another routine! However the functions are terminated with a }; (Why?)
Here is another answer:
var M_A = function()
{
var m_a; //private variable
this.get = function()
{
return m_a;
}
this.set = function(value)
{
m_a = value;
RunFunction(); //run some global or private function
this.runPublic(); // run a public function
}
}
This guy kinda answers the question but all of the functions are terminated with a } with no semicolon following (Why?)
Finally the answer is unsatisfactory, What is a global or private function? and what is a public function? Why does the public function refer to "this". Anyhow I am probably the village idiot but I still do not know how to call a function I have defined in the class from within the class, and I don't know whether the termination of functions inside a class should be with a }; or just a }. So I have now spent almost 12 hours trying to get one little class to work in javascript to no avail.
Two things are tripping you up.
The first one is the difference between function declarations and function values.
This is a function declaration:
function foo() {
// ...
}
These are function values:
var bar = function() {
// ...
};
var bar = function foo() {
// ...
};
baz(function() {
// ...
});
Function declarations do not need semicolons. Function values are not full statements; full statements do need them (sometimes). It is important to note that in these last three examples, the semicolon does not terminate the function, it terminates the var statement and the function evaluation statement.
This "(sometimes)" is the second point where you have a problem: in JavaScript, a semicolon will be automatically inserted at newline if it is obvious to the interpreter that it should be there.
So,
x = 5
y = 6
is identical to
x = 5;
y = 6;
Thus,
var bar = function() {
// ...
}
is identical to
var bar = function() {
// ...
};
But look at this:
var bar = function() { /* ... */ }; console.log(bar);
is okay (all needed semicolons are there);
function bar() { /* ... */ } console.log(bar);
is also okay, since the function declaration statement does not need a semicolon. However,
var bar = function() { /* ... */ } console.log(bar);
is an error, as the variable assignment statement cannot be separated properly from the function invocation statement. Note that due to automatic semicolon insertion, this works:
var bar = function() { /* ... */ }
console.log(bar);
EDIT: There is a semantic difference between a function declaration statement and assigning a function value to a variable: function declaration statements are executed first (this is called "function hoisting"), while assignments are, as all assignments, executed in order:
function pre_fn() {}
var pre_var = function() {};
pre_fn(); // works
pre_var(); // works
post_fn(); // works
post_var(); // error (not defined yet)
function post_fn() {}
var post_var = function() {};
EDIT2:
I suspect that the class that you were unable to create (as said in comments, code in the question would have been better than speculation) had an object literal form:
var Foo = {
bar: function() {
// ...
},
baz: function() {
// ...
}
};
Here, the semicolon terminates the var Foo = { /* ... */ } statement. You can't have semicolons inside it, for the same reason you can't write
var foo = { a = 6; b = 7 }
because the syntax of the object literal mandates that you separate the key-value pairs with commas. There is no difference here between the numeric value 6, and the function value function() { /* ... */ }; neither "terminates" with a semicolon.
I was playing around with javascript objects to understand "this" and function context better. I stumbled across this problem. I get the error "obj2 is not defined" unless I run window.obj2() after assigning it, but I don't know why. Shouldn't it be enough to assign the function to window.obj2 without also executing it immediately afterwards? I know that you're not supposed to pollute the window object, this is just a test.
Thanks!
window.obj2 = function(){
console.log('obj2 in window.object',this);
}
window.obj2(); // problem when this line is commented out
(function () {
var parent = {
obj : function(){
//console.log(this);
obj2();
this.obj2();
window.obj2();
},
obj2 :function(){
console.log('obj2 in parent',this);
}
}
parent.obj();
}());
EXPLANATION
OP asks why does he have to execute the function after defining it in order for it to become defined later in the code... See what happens when you comment out the problem line.
Solution to the mystery:
You forgot a semicolon:
window.obj2 = function(){
console.log('obj2 in window.object',this);
}; // <--
Without it, the code will be interpreted as
// I'm naming the functions to refer to them later
window.obj2 = function a(){
...
}(function b() { ... }());
I.e. the parenthesis around b are interpreted as call operation of a (just like you did with b itself: (function b() {...}()).
The engine first executes b in order to pass the return value as argument to a, and only after that the return value is assigned to window.obj2.
So, at the moment b is called, window.obj2 does indeed not exist yet.
So, the reason why adding window.obj2() makes it work is not because you are accessing window.obj2, but because it makes the code un-ambigious. The following parenthesis cannot be interpreted as call operation anymore. You could use any statement there, e.g.
window.obj2 = function(){
console.log('obj2 in window.object',this);
}
"foo";
(function () {
obj2();
}());
If you defined function window.obj2 inside the anonymous function which does call itself then it works fine, have a look code.
<script>
//window.obj2(); // problem
(function (window) {
window.obj2 = function(){
console.log('obj2 in window.object',this);
}
var parent = {
obj : function(){
//console.log(this);
obj2();
this.obj2();
window.obj2();
},
obj2 :function(){
console.log('obj2 in parent',this);
}
}
parent.obj();
}(window));
</script>
<body>
</body>
What is the different between two declarations of a module in JavaScript?
One has parentheses around the function and other one doesn't?
One article says that
Notice the () around the anonymous function. This is required by the
language, since statements that begin with the token function are
always considered to be function declarations. Including () creates a
function expression instead.
Both seem to do the same thing when checked.
var person = (function () {
// Private
var name = "Robert";
return {
getName: function() {
return name;
},
setName: function(newName) {
name = newName;
}
};
}());
var person = function () {
// Private
var name = "Robert";
return {
getName: function() {
return name;
},
setName: function(newName) {
name = newName;
}
};
}();
Functions are of two types in JavaScript - declarations and expressions.
This is the difference between the two:
Function declarations are hoisted. This means you can call the function before it appears in the program as declarations in JavaScript are hoisted.
Function expressions can be invoked immediately. A function declaration cannot. This is because expressions express (or return a value). Function expressions express a function.
An example of a function declaration:
foo("bar");
function foo(bar) {
alert("foo" + bar);
}
The above program will work because foo is a function declaration.
foo("bar"); // throws an error, foo is undefined - not a function
var foo = function (bar) {
alert("foo" + bar);
};
The above program will not work as foo is declared as undefined, hoisted and then later assigned the value of a function expression. Hence it's undefined when it's called.
An example of a function expression:
(function (bar) {
alert("foo" + bar);
}("bar"));
The above function will be immediately invoked as it's a function expression.
function (bar) {
alert("foo" + bar);
}("bar"); // throws an error, can't call undefined
The above function will not be immediately invoked as it's a function declaration. Remember, declarations do not express (or return a value). So it's like trying to invoke undefined as a function.
How does a function become an expression?
If a function is used in the context where an expression is expected then it's treated as an expression. Otherwise it's treated as a declaration.
Expressions are expected when:
You're assigning a value to a variable (i.e. identifier = expression).
Inside parentheses (i.e. ( expression )).
As an operand of an operator (i.e. operator expression).
Hence the following are all function expressions:
var foo = function () {};
(function () {});
~function () {};
Everything else is a function declaration. In short if your function is not preceded by anything, it's a declaration.
See this code: https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94
The following function isExpression is used to test whether some arbitrary JavaScript code is an expression or not:
function isExpression(code) {
if (/^\s*function\s/.test(code)) return false;
try {
Function("return " + code);
return true;
} catch (error) {
return false;
}
}
Hope this clears any doubts in your mind.
In short:
A function expression expresses or returns a value (in this case a function). Hence it can be immediately invoked, but it can't be called before it appears in the program.
A function declaration is hoisted. Hence it can be called before it appears in the program. However since it doesn't express any value it can't be immediately invoked.
In the current context there's no difference for the interpreter. Usually preferable way of writing module is by wrapping the function with parentheses:
var person = (function () {
// Private
var name = "Robert";
return {
getName : function () {
return name;
}
};
}());
That's because the syntax is cleaner and it's obviously that you want to invoke the function immediately after it is declared. One more reason is because:
(function () {
//some stuff
}());
will work but
function () {
//some stuff
}();
this wont.
By wrapping the function each time you use common codding style which is usually a good thing :-).
The difference is that when writing:
var foo = (function () {
...
}());
the use of the (superfluous but useful) grouping () is a common coding style to make it clear from very like first line that the right hand side is most likely an immediately invoked function expression (IIFE). However, in the second:
var foo = function () {
...
}();
it doesn't become apparent until you read the last line, which might be quite a few lines down. Until you reach the last line, you probably thought you were reading a plain assignment:
var foo = function () {
...
};
Note that the parenthesis can be used in a plain assignment too:
var foo = (function () {
...
});
but in that case they really are superfluous (and probably misleading due to the convention of using them for IIFEs).
See An Important Pair of Parens.
I'm studying object literals and self-executing functions in Javascript. Looking through some YUI code I came across some methods of an object literal that execute themselves. My question is why the following code does not alert 'Ohai Mark!';
var bar = {
alert: function () {
window.alert('Ohai Mark!');
},
init: (function () {
bar.alert();
}())
};
To explain in detail:
> var bar = {
In javascript, declarations are processed first so bar exists as a variable before execution begins.
> alert: function () {
> window.alert('Ohai Mark!');
> },
> init: (function () {
> bar.alert();
> }())
bar will be assigned a value after the expression on the right hand side is evaluated. During that evaluation, bar has whatever value it had when the statement (the entire line) was reached. It is currently undefined, and so it does not have an alert property yet.
> };
When executing the code, "bar" is defined but not yet assigned the resultant JSON object at the point which the init() method is defined (and about to assigned to the bar object) [EDITED]. As init's function-scope is properly defined, I would declare the function there, like so:
var bar = {
init: (function () {
var alert = function () {
window.alert('Ohai Mark!');
};
alert(); //this will execute the code above
}())
};
See Javascript Garden#namespaces and scopes. [EDIT] You might think this akin to:
(function() {
var c = c + 1;
})();