The code in https://github.com/mattdiamond/Recorderjs/blob/master/recorder.js
I don't understand the javascript syntax like
(function(window){
// blah-blah
})(window)
When I tried the code follow, I could see "hello world" in the console.
(function(window){
console.log("hello world");
})(window)
What does this mean?
Any references?
Thanks in advance
What does this mean? Any references?
It simply executes the bracketed function, just as if it's splitted as:
f = (function(window){
console.log("hello world");
})
f(window)
In any JavaScript file if you write something like:
justFunction();
//function declaration
function justFunction()
{
alert("something");
}
This will call the justFunction() and show an alert. Defining a function like that is known as function declaration.
Now there is another way to define a function
var anotherFunction = function() { alert ("something")}
Now if you write something like
anotherFunction();
// Function Expression
var anotherFunction = function() { alert ("something"); }
Although anotherFunction is a function here this will give an error in console. This is known as function expression.
The reason behind that is function declarations loads before any code is executed. While function expressions loads only when the interpreter reaches that line of code. So if you try to call a function expression before it's loaded, you'll get an error.
But if you call a function declaration, it'll always work. Because no code can be called until all declarations are loaded. So you will have to always call the function expression after it is defined.
// Function Expression
var anotherFunction = function() { alert ("something"); }
anotherFunction();
Now a function expression can be called immediately by adding parenthesis after the anonymous function like
var anotherFunction = function() { alert ("something"); }(); //paranthesis added
This code snippet and the above does the same thing (shows the alert). Now the anotherFunction variable is not the same as above because it is now assigned with the value , that the anonymous function will return. Right now it is not returning anything so anotherFunction is undefined. So if you write something like
var anotherFunction = function() { alert ("something"); }();
anotherFunction(); //error
This will give an error, because the anonymous function does not return any function. If its returns something like
var anotherFunction =
function() { alert ("something"); return "some string"; }(); //returns string
anotherFunction is now a string variable. And if:
var anotherFunction = function() { alert ("something"); return function(){
alert("somethingElse")
}; }(); // returns function
Now anotherFunction is a function and can be called like anotherFunction().
You can pass parameters to this function expression like
var anotherFunction = function(p1,p2) { console.log(p1);
console.log(p2); }(param1,param2 ); //param1,param2 are parameters
One of the main difference between a function expression and a function declaration is that A function expression can be called (invoked) immediately by using a set of parentheses, but a function declaration cannot be.
Now if we don't want to assign the function expression to a variable, then we have to write it inside parenthesis.
(function() { alert ("something");});
And to call it we need to add another set of parenthesis at the end like
(function() { alert ("something"); }());
And same as earlier, we can also pass parameters to it like:
( function(param){ console.log(param); }(param));
This type of functions are ## Heading ##called IIFE (Immediately Invoked Function Expression).
IFFE is just an anonymous function (no name attached to it) that is wrapped inside of a set of parentheses and called (invoked) immediately.
( function(){ }());
REFERNCE
Consider this example.
var message = 'hello world';
function Say(msg){
console.log(msg);
}
new Say(message);
You can make it self invoking anonymous function by wrapping the Say() without a name with parentheses and adding another parentheses after it and pass the message to it.
(function(msg){
console.log(msg);
})(message);
Related
How to call a function expression which being nested inside another function ?
let a = function() {
//do something
let b = function() {
console.log('Hello World!')
}
}
a();
There are different ways to define functions in Javascript like Function declaration, Function expression and Arrow functions.
Function declaration can be defined as follow :
function a() {
alert("a");
}
and you can call it by its name a()
and the second is function expression which can be defined in two ways:
//Anonymous Function Expression
let anotherFn = function(){};
//Named function Expression
let anotherFn = function b() {};
you can only call the above function as anotherFn()
In anonymous function expression, the function is assigned to a variable and that function can only be called by the variable name. An anonymous function expression doesn't have any name.
However, you can also provide the name to the function expression. It is useful when you want to refer the current function inside the function body, e.g. in case of recursion. But the name is only accessible within the function body and can't be used to invoke the function outside.
That's why you are getting error b is not defined.
See function expression:
Syntax
var myFunction = function [name]([param1[, param2[, ..., paramN]]]) {
statements
};
[...]
name
The function name. Can be omitted, in which case the function is anonymous. The name is only local to the function body.
Note the last sentence.
why should i use variable to call a function and put parentheses after it?
You can define functions either as a function statement or as an expression. See var functionName = function() {} vs function functionName() {} for more information.
I though that once createFunction runs I'll have access to the inner function.
function createFunction() {
function printHello() {
return console.log("hello");
}
return printHello;
}
// Both of these return undefined
createFunction(printHello());
createFunction.printHello();
Any thoughts?
Proper syntax is:
createFunction()();
... or, a bit more wordy:
const returnedFunction = createFunction();
returnedFunction();
... as printHello name makes any sense only within createFunction, but its value is actually returned by that function. And yes, it's perfectly ok to place any number of () in sequence you want.
As a sidenote, returning the result of console.log('hello') makes little sense: logging itself is a side effect, no need to check its result.
I though that once createFunction runs I'll have access to the inner function.
No, you cannot access a variable that is inside of a function outside of it. If you call a function those variables exist, but you cannot access them. However if a value gets returned, you can work with the function call as if it would be that expression. In your case you return the function so you can access it as:
var print = createFunction();
print();
Or as a oneliner:
createFunction()();
In your code createFunction returns another function, so to execute inner function you must call inner function by appending () after return value of createFunction i.e createFunction()();
createFunction() give printHello = function definition
createFunction() () same as printHello**()**
Also if we simplify your code we can re-write as
function printHello() {
console.log("hello");
};
function createFunction() {
return printHello;
};
console.log("return value of: createFunction()");
console.log(createFunction());
console.log("return value of: createFunction() () --> printHello()");
createFunction()();
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>
Does a Javascript self executing function work like a compiled program. I.e can you declare some function after a named anonymous function within a self executing function and have the named anonymous function locate the other function at runtime? I.e why does the following work?
I'd thought that you could not hoist named anonymous functions as they are only created during runtime so perhaps the self executing function "compiles" the code to make the named anonymous function available to the function that calls it!!
(function(){
var myFunc = function(){
var bar = "Bar";
return myFunc2() + bar;
}
function myFunc2(){
return "Foo ";
}
})()
or even
(function(){
function myFunc(){
var bar = "Bar";
return myFunc2() + bar;
}
var myFunc2 = function(){
return "Foo ";
}
window.fooBar = myFunc();
})()
console.log(fooBar);
That particular example works because myFunc2 is never called because myFunc is never called.
In general though, the normal rules for JS scope, hoisting and timing apply:
A variable must be populated before you use it, not before you define a function that will use it when called.
Lets see what actually happens in your code.
1.you have a function that performs a variable assignment:
var myFunc = ;
2.you declare a function. (But don't yet invoke it)
3.you assign myFunc to window.foobar.
4.And you invoke the function you were defining.
Now, these steps happen:
myFunc gets a function as its value.
myFunc2 gets defined.
window.foobar gets the result of calling myFunc().
so what happens is, myFunc() returns the result of invoking myFunc2() and appends its result to bar.
Thus, the value of window.foobar will be "foobar".
(no, this is not how compiled programs work)
(function(){
var myFunc = function(){
var bar = "Bar";
return myFunc2() + bar;
}
function myFunc2(){
return "Foo ";
}
})()
After some hoisting this becames:
(function(){
var myFunc;
function myFunc2(){
return myFunc2() + bar;
}
myFunc = function(){
var bar = "Bar";
return "Foo ";
}
})()
And actually this will work if you call myFunc(); and log the returned value from myFunc2 you will get Foo Bar.
When hoisting named anonymous functions(which is actually function expression), only
var myFunc (= undefined); is hoisted. Then the assignment stay at the same level.
Also you cant refer this function as self execution function(because self executed function is actually recursion). This is Immediately Invoked Function Expressions.
And #Quentin said the rest: A variable must be populated before you use it, not before you define a function that will use it when called.
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.