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.
Related
i'm learning about functions. i'm confused in one scenario.
suppose i have three functions
<script>
var fnRef = function() {
console.log("i'm function with no name but refered to fnRef");
};
var funRef2 = function test() {
console.log("im test reffered to funRef2");
};
function test2() {
console.log("i'm test2 named function")
};
</script>
fnRef, fnref2 and test2 will be assigned to window as a property as fnRef and fnRef2 are variable and test2 is named function that act as variable.
but why test2 is not assigned to the global object(window) when refered by funref2? and why i'm not able to execute test(); can someone tell me what is happening in detail.
The named function expression is useful so you can access the function inside it's own scope without using arguments.callee, and it also makes it easier when debugging as the name can be seen in stack traces, breakpoints etc.
This name is then local only to the function bodys scope, meaning
var test1 = function test2() {
if (something) test2(); // available in this scope only
}
test2(); // not here
You can't call the function by it's name, only by the variable it's assigned to, as the functions name is limited to the functions scope when it's a function expression.
When defining a function declaration, the name is assigned to the current scope, and hoisted, so this
var bar = test();
function test() { return 'foo'; }
is more or less turned into this
var test = function() { return 'foo'; }
var bar = test();
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>
david sharif made a JS quiz which pretty much looks like-
var foo=1;
function bar(){
return foo;
foo=10;
function foo(){}
var foo =5;
}
typeof bar();//?
In my understanding, functions are hosited first and then variable declared inside. the hosited form of the function would be something like (correct me if i am wrong)-
var foo=1;
function bar(){
function foo(){}
var foo;
return foo;
foo=10;
foo =5;
}
typeof bar();//?
why typeof bar() is function not undefined?
Is this because of, at the time of function execution, it finds the first foo (which is a function) and returns happily without continuing search. Or something else?
Appreciate your time.
I found the answer in David Shariff blog.
"Shamelessly copied from his blog"-
Even though foo is declared twice, we know from the creation stage that functions are created on the activation object before variables, and if the property name already exists on the activation object, we simply bypass the declaration.
Therefore, a reference to function foo() is first created on the activation object, and when we get interpreter gets to var foo, we already see the property name foo exists so the code does nothing and proceeds.
If this sound like greek, read the whole blog
The Function Declaration "shadows" the var statement.
Paste this in to your console:
var foo = function(){}
var foo
typeof foo
This is how the code "looks like" to the Interpreter after compiletime:
var bar = function bar(){
var foo = function foo(){}
foo
return foo;
// never reached
foo = 10;
foo = 5;
}
var foo;
foo = 1
typeof bar();//"function"
Function declarations are evaluated upon entry into the enclosing scope, before any step-by-step code is executed. The function's name (foo) is added to the enclosing scope (technically, the variable object for the execution context the function is defined in).
Example 1
From this example wecan see that even we are declaring foo after the return statement, we can still get foo returned.
function bar() {
return foo;
function foo() {} // this will get initialized before the return statement.
}
console.log(typeof bar()); // this will be function
Example 2
From this example we can see that if we are declaring our variables in a normal way after the return statement, they will not execute(assigned).
Declare function after return.
function bar() {
return foo;
var foo = function() {} // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Declare number after return
function bar() {
return foo;
var foo = 12; // this will not get assigned
}
console.log(typeof bar()); // this will be undefined
Example 3
Now let's walk through a messier example line-by-line.
function bar() {
return foo;
function foo() {} // <-- initialize foo as a function
var foo = 11; // <-- this will not get assigned
}
console.log(typeof bar()); // function
I hope the above example will not only answer you question but also give you a better understanding of:
var foo = function() {} vs function foo() {}
In below example about Scope, I dont understand that how could a variable is running as a function? in here var f is running as f(). However, is this a sound method to run f in JavaScript? Why? Is it because var f stored a function?
var myFunction = function() {
var foo = "hello";
var myFn = function() {
console.log( foo );
};
foo = "ddd";
return myFn;
};
var f = myFunction();
f(); // "ddd"
Thanks!
This line of code will run the function myFunction and assign its return value to f.
var f = myFunction();
myFunction returns a reference to the function myFn. As a result, f is now a reference to myFn and when you attempt to call f using f() it calls myFn because that is where the reference points.
jsFiddle Demo
There is a similar approach which returns an object with functions
var init = function(){
return {
hello: function(){ console.log("hello"); },
world: function(){ console.log("world"); }
};
};
Which could then be used like this:
var f = init();
f.hello();
f.world();
In scripting languages in general and functional programming. You can use functions as you would a variable. For example: in both paradigms typically(not aware of any languages that don't) functions can be passed as parameters, etc...
Functions are objects in javascript, so they can be assigned to variables and passed around like any other value. And eventually they can be executed.
What's happening here is that myFunction returns a function, which can then of course be executed.
Let me simplify your example:
// function that returns a function.
var foo = function() {
// declare a function, but don't run it right now.
var fn = function() {
return "bar";
};
// return the function object.
return fn;
}
var someFn = foo(); // function object is returned from foo()
someFn(); // "bar" is returned
// Which means you could also do this!
// the first () executes foo, second () executes the function returned by foo()
foo()() // "bar" is returned
In this example, foo() returns a function. This function is saved to the local variable someFn and then executed.
Functions that return functions are a little tricky to wrap you head around sometimes, but it's one of the most powerful features of javascript as it allows you do some very tricky things.
<script type="text/javascript">
function func(){
}
var foo="foo";
</script>
<script type="text/javascript">
var foo="foo";
function func(){
}
</script>
At the beginning, when func is a function and foo is "undefined", but I want to know which is the first to be defined, func or foo?
Identifiers of both, variable and function declarations (and also formal parameters for function code) are made when entering the execution context, that's actually before the code execution.
In the case of variables, as you noted it, they are initialized with the undefined value at that stage, the assignment takes places after, when control reaches the assignment expression, e.g.:
var foo = "outer";
(function () {
alert(foo); // undefined
var foo = "inner";
})();
In the above code, we can see how the foo identifier holds the undefined value, that's because when entering the function execution context, the local foo variable was initialized.
That's one of the reasons why people recommend to declare your variables at the top of the function (to resemble what actually happens)
Functions declarations are also hoisted, you can actually use them before its declaration, because as we know, it was made before the code execution, for example:
func(); // "bar"
function func () {
return "bar";
}
See also:
Variable Instantiation Process
In
var foo = "foo";
function func() {
}
there are two things going on
Declaration
Initialization
foo and func are declared simoultaneously.
The initialization of func is hoisted to the top. So functions are initialized before vars.
So the order of operations is
foo and func declared
func initialized to a Function object
foo initialized to "foo"
This is clearest in the code
var foo = bar;
function bar() {}
where after this code runs, typeof foo === 'function'.
I believe identifiers become defined as their declarations are encountered.
Functions in javascript are always parsed and defined first.
<script type="text/javascript">
alert('before func: ' + func); // Print function as string
alert('before somevar: ' + somevar); // Print undefined
function func() {
}
var somevar = "hello";
alert('after func: ' + func); // Print function as string
alert('after somevar: ' + somevar); // Print hello
</script>