This question already has answers here:
What is the purpose of a self executing function in javascript?
(21 answers)
Closed 7 years ago.
I am new to javascript and I might have dove into the deep end first. I have came across the following definition while reading design patterns in js. I don't understand the syntax used here, why is the "log" function definition in "()",
var log = (function() {
var log = "";
return {
add: function(msg) { log += msg + "\n"; },
show: function() { alert(log); log = ""; }
}
})();
Please point me in the right direction.
Without the parenthesis, the right hand side of your assignment is a function expression, and log is assigned a reference to that (anonymous) function expression, allowing to call log() later.
If you include the parenthesis, the wrapped function turns into a self-invoking function expression (and is immediately executed), so log is assigned whatever this function call returns.
As someone else already stated, your code shows an example of the so-called module pattern. Read much more about it here.
I don't understand the syntax used here, why is the "log" function
definition in "()"
Its basically self executing anonymous function. There are several ways of writing such functions.
(function() {
alert('hi there');
})();
! function() {
alert('hello');
}();
+ function() {
alert('plus');
}();
- function() {
alert('minus');
}();
Now such function can also return values:
var msg = (function() {
return 'hello';
})();
alert(msg);
var calc = (function() {
return {
add: function(a, b) {
return a + b;
},
sub: function(a, b) {
return a - b;
}
};
})();
alert(calc.add(4, 5));
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.
This question already has answers here:
Are "(function ( ) { } ) ( )" and "(function ( ) { } ( ) )" functionally equal in JavaScript? [duplicate]
(3 answers)
Closed 8 years ago.
We can have immediately invoking function in two ways. I am confused about what is the difference between the following
var foo = function(){
return { };
}();
and this :
var foo = (function(){
return { };
}());
Exactly the same.
// This one creates a function expression, then executes that function expression.
var foo = function(){
return { };
}();
// This one creates a function expression, inside of a set of parens.
// the parens hold an expression.
var foo = (function(){
return { };
}());
The parens are used for two reasons:
1) In this context, they are a clue to the READER, not to the compiler, that you have an IIFE.
2) In other contexts, the parens force a expression, when a function statement might be generated.
// The parens here force an expression, which means it forces a function expression
// instead of a function statement.
(function () {....})
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Is there a way to wrap all JavaScript methods with a function?
(3 answers)
Closed 8 years ago.
Here's what I want to achieve:
var obj = {
something: 1,
someFunction: function () {
return 'hello';
}
};
wrap(obj).someFunction('hello'); // this should be different from obj.someFunction defined above
wrap(obj).something = 2; // this should still work
Basically, I want to 'wrap' an object and replace all the functions in it with something else.
Here's how I've defined the wrap function:
function hello (v) {
return 'Hello ' + v;
}
function wrap (oldObj) {
var newObj = {};
for (var k in oldObj)
Object.defineProperty(newObj, k, {
get: function () {
if (typeof oldObj[k] === 'function')
return hello;
return oldObj[k];
},
set: function (val) {
oldObj[k] = val;
}
});
return newObj;
}
(hello is just an example replacement function)
When I try to use this, everything in obj gets replaced with a function (i.e even obj.something, which was set to 1, is replaced with a function). I can't seem to find any issues with this code. I've tried debugging it and haven't found the issue yet.
What might be the issue? How else can I solve this problem?
Edit 1: I don't want to replace functions in the object itself, I want to create an entirely new object.
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.