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.
Related
This question already has answers here:
Why does `obj.foo = function() { };` not assign the name `foo` to the function?
(3 answers)
Closed 4 years ago.
Suppose I have an 2 objects x and y. The details are written in the code below.
let x = {
publish: function() {
console.log(this.publish.name);
}
};
let y = {};
y.publish = function() {
console.log(this.publish.name);
};
x.publish();
y.publish();
I was getting difference in the outputs calling x.publish() and y.publish().
The former returned the name of the function while the latter returned empty. Can anyone explain why is this happening, and is there any other
possible way I can retrieve the function name in latter(WITHOUT HARDCODING). I am using NodeJs version 8.
Since the function in the second case doesn't have any name associated with it so you get empty string.
let x = {
publish: function() {
console.log(this.publish.name);
}
};
let y = {};
y.publish = function() {
console.log(this.publish.name);
};
let z = {};
z.publish = function hello() {
console.log(this.publish.name);
};
x.publish();
y.publish();
z.publish();
In your second case y.publish, you're assigning a variable identifier to the function but not giving it a name. that would be y.publish = function publish()
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
Search for SetFunctionName on the following:
1. Property initializer semantics
2. Assignment Operator Semantics
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.
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:
What is the (function() { } )() construct in JavaScript?
(28 answers)
Closed 9 years ago.
I got so confused here. Can someone help me peel the layers off the function definition here? What are the out-most parentheses for? Why argument (p) can be after }, and which function is it for? Where is q required at all? Why can p directly call publish() later?
var p = {};
(function(q) {
q.publish = function(topic, data){
...
};
}(p));
...
p.publish("inbox", "hello");
It simply creates the function and executes it immediately.
For example:
var foo = function() {
return 5;
}();
console.log(foo);
will print 5.
If you want to learn more about it, please read this excellent article http://benalman.com/news/2010/11/immediately-invoked-function-expression/
I would like to quote module pattern example from the link I shared.
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
}());
console.log(counter.get());
counter.set(3);
console.log(counter.increment());
console.log(counter.i);
Output
0
4
undefined
Here we are dynamically creating an Object at the same time we are making i private. This is called closure property.
Putting the function in parentheses means the JS interpreter takes it as a function expression, so it can be anonymous (i.e., not have a declared name). Adding () at the end means the function is called immediately. So, e.g.:
(function() {
alert('Hi');
}());
...declares a really simple function with no arguments, and calls it immediately. A slightly more complicated one with an argument might look like this:
(function(someArgument) {
alert(someArgument);
}('Hi'));
That would alert 'Hi', because the string 'Hi' is passed to the anonymous function when it is called.
So with that as background, here's what your code is doing line by line:
var p = {}; // declare variable p, referencing an empty object
(function(q) { // make an anonymous function expression that takes one argument, q
q.publish = function(topic, data){ // add a property 'publish' to whatever q is,
... // where 'publish' is a function that takes
}; // two arguments
}(p)); // call the anonymous function, passing p in
...
p.publish("inbox", "hello"); // call the method 'publish' that was added to p
The q argument that you asked about takes the value from p, so it refers to the same empty object, but then it adds the .publish() method to that object.
This general concept is called an "Immediated invoked function expression", or IIFE.
Usually if an IIFE is just sitting there by itself like that (i.e., another variable is not assigned equal to it) it is done so that working variables/functions can be created temporarily without adding them to the global scope, because in JavaScript the scope options are basically global or function. The code you show doesn't do that, but here's a simple example:
(function() {
var x = 0;
for (var i = 0; i < 100; i++)
x += i;
alert (x);
}());
// here x and i are not accessible because they're local to the function above.
It's a self executing function. Using q is useless here since q === p.
var p = 'hello';
function f(q){ return q; }; f(p); // "hello"
(function(q){ return q; }(p)); // "hello"
(function(){ return p; }()); // "hello"
/*(*/function(){ return p; }()/*)*/; // SyntaxError: Unexpected token (
This pattern is usually used to create a private context for variables. Here is a well known example :
var counter = function(){
var i = 0;
return function(){
return ++i;
};
}();
counter(); // 1
counter(); // 2
i; // undefined
Have a look at this great article : http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html.
This question already has answers here:
Location of parenthesis for auto-executing anonymous JavaScript functions?
(4 answers)
Closed 8 years ago.
Both of these code blocks below alert foo then bar. The only difference is })() and }()).
Code 1:
(function()
{
bar = 'bar';
alert('foo');
})();
alert(bar);
Code 2:
(function()
{
bar = 'bar';
alert('foo');
}());
alert(bar);
So is there any difference, apart from the syntax?
No; they are identical
However, if you add new beforehand and .something afterwards, they will be different.
Code 1
new (function() {
this.prop = 4;
}) ().prop;
This code creates a new instance of this function's class, then gets the prop property of the new instance.
It returns 4.
It's equivalent to
function MyClass() {
this.prop = 4;
}
new MyClass().prop;
Code 2
new ( function() {
return { Class: function() { } };
}() ).Class;
This code calls new on the Class property.
Since the parentheses for the function call are inside the outer set of parentheses, they aren't picked up by the new expression, and instead call the function normally, returning its return value.
The new expression parses up to the .Class and instantiates that. (the parentheses after new are optional)
It's equivalent to
var namespace = { Class: function() { } };
function getNamespace() { return namespace; }
new ( getNamespace() ).Class;
//Or,
new namespace.Class;
Without the parentheses around the call to getNamespace(), this would be parsed as (new getNamespace()).Class — it would call instantiate the getNamespace class and return the Class property of the new instance.
There's no difference - the opening brace only serves as a syntactic hint to tell the parser that what follows is a function expression instead of a function declaration.
There's no difference. Both are function expressions.
There is be a third way, too:
+function() {
bar = 'bar';
alert('foo');
}();
(instead of the + another operator would work, too)
The most common way is
(function() {
// ...
})();
though.