Javascript: When does a global get created - javascript

At what point would the global variable be created in the following function below; before test() is executed or after?
var test = function(){
foo = 5
}
test()
Edit: I am referring to foo variable

..before test() is executed or after?
It depends which global variable you're referring to, test or foo.
For test: Before. var declarations are "hoisted," they're processed before any step-by-step code in the scope where they appear is executed; global ones are executed prior to any step-by-step code at global scope in that script. (Subsequent scripts are handled separately, first vars, then step-by-step code.)
For foo: During.
The order of that code is:
Declarations occur:
The global test is created with the value undefined.
Step-by-step execution is done:
The assignment test = function() { foo = 5 } is executed
The function is created
It's assigned to test
test() is executed
The assignment foo = 5 is done, creating an implicit global called foo (more on my blog: The Horror of Implicit Globals)

This is easy enough to test:
// The code within the function won't be evaluated (nor any variables within it be hoisted)
// until that code is invoked
var test = function(){
foo = 5;
}
// This will fail saying that foo is undefined, so we know that the global
// hasn't been created yet
//console.log(foo);
// Call the function and force the code within it to be evaluated
test()
// Works. The global has been created..
console.log(foo);

The variable foo will be create when an interpreter will try to assign the variable foo, so during the function execution.
var test = function(){
foo = 5
}
window.hasOwnProperty('foo'); // false
test()
window.hasOwnProperty('foo'); // true

Here in your code
var test = function(){ foo = 5};
test();
test is the global variable which holds the Function object. It is created before test() function invocation during global execution environment .
foo is also global variable as no var, let or const keyword is there. But it will be created after invocation of test() function.

Related

Are functions defined regardless of the order?

I'm not really a javascript noob at all, although in my whole life I've never came across this, but am I right in assuming that javascript must assign functions before running anything or something?
In all my experience, I expected this to return 'undefined', but obviously it returns 'function'.
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
alert(typeof bar());
Is someone able to explain this for me?
This behaviour of JavaScript is called hoisting. There is a good explanation on the MDN (https://developer.mozilla.org/en-US/docs/Glossary/Hoisting)
In JavaScript, functions and variables are hoisted. Hoisting is JavaScript's behavior of moving declarations to the top of a scope (the global scope or the current function scope).
That means that you are able to use a function or a variable before it has been declared, or in other words: a function or variable can be declared after it has been used already.
Basically, if you declare a variable like this:
console.log(s); // s === undefined
var s = 'some string';
s declaration will be "hoisted" to the beginning of the scope (i.e. there will be no ReferenceError on the line with console.log). The variable's value will not be defined at that moment though.
The same goes with assigning an anonymous function to a variable, so:
console.log(f); // f === undefined
f(); // TypeError: f is not a function
var f = function () {}; // assigning an anonymous function as a value
f(); // ok, now it is a function ;)
The variable will be hoisted and thus visible in the entire scope, but it's value, even if it's a function, will still be undefined - hence the error if you try to execute it.
On the other hand if you declare a named function:
console.log(f); // f === function f()
f(); // we can already run it
function f() {}; // named function declaration
It's definition will also be hoisted so you can run it even in the first line of the scope you've declared it.
This is quite easily tested;
foo(1);
function foo(i) {
if (bar()) {
alert("foo called, bar true, i = " + i);
};
}
foo(2);
function bar() {
return true;
}
foo(3);
DEMO
This shows that Javascript loads all functions before executing anything. Therefor it does not matter what order functions are defined.
Well in JavaScript function is nothing but Object.
When you say typeof bar(),in the bar function you are returning foo which is another function.You just returning name of the function,So,it return the constructor of the foo function.So,your typeof get the value of foo constructor which is type of function.So,it alert function.It still refer the foo because of closure
Again in the bar defination,you returning foo,but its definition is still not encountered.In JavaScript when while parsing the instruction,declaration of variable and function is placed on top in current function scope.
So,
your statement
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = '11';
}
is equivalent to
function bar() {
function foo() {}
return foo;
foo = 10;
var foo = '11';
This is called JavaScript top hoist
}

A better understanding of javascript precompile

var foo=1;
function bar(){
foo=10;
return;
function foo(){}
}
bar();
alert(foo);
I am currently learning on how javascript is actually running in the machine and this is a piece of code I see in the example. I got no idea why the final alert is 1 instead of 10. So I am wondering could any one help me explain how the javascript virtual machine is actually execute these code. Thanks!
This is due to function declaration hoisting:
var foo=1;
function bar(){
function foo(){} // This gets moved up here by the engine
foo=10; // You've reassigned the local `foo` function to 10,
// leaving the global `foo` untouched
return;
}
bar();
alert(foo); // Since the foo has never changed in this scope, it's still 1
I got no idea why the final alert is 1 instead of 10.
Because the foo in this line in bar:
foo = 10;
...is the variable-like thing* declared by the function declaration later on in that function:
function foo(){}
...not the foo that's outside bar. That is:
var foo=1;
function bar(){
foo=10; // <== This `foo`
return;
function foo(){} // <== Is the `foo` declared here
}
bar();
alert(foo);
...not to the foo declared in the containing scope (var foo).
There are two reasons that's happening:
Function declarations are processed immediately on entry to the containing scope (the call to bar, in this case), prior to any step-by-step code in the function. This is sometimes called "hoisting" the declarations (because they happen as though they were at the very top). And since the function declaration isn't step-by-step code, the return has no effect on whether it gets processed; it gets processed before the return ever happens.
Function declarations also create what might as well be variables with the names of the functions. So the foo in the function declaration effectively becomes a variable with that name (more below) — and as you've seen in that code, you can assign new values to those "variables."
When you run that code, here's the order of things that the JavaScript engine does:
Creates a variable called foo and gives it the initial value undefined.
Creates the function bar, adding bar as an in-scope symbol (effectively a variable) in the current scope and making it a reference to the bar function.
Starts step-by-step code for that scope.
Assigns the value 1 to foo.
Calls the bar functon.
Creates the foo function relevant to that call to bar, adding foo as an in-scope symbol (effectively a variable) during the call and making it a reference to the function.
Starts the step-by-step code for that scope.
Assigns the value 10 to the local foo (which used to refer to the function).
Returns out of the function.
Calls alert with the foo in that scope, which still has the value 1.
You can read up on all the gory details in §10.4.3 of the spec and the sections it links to.
* "variable-like thing" In JavaScript, each execution context (the global context and any contexts created by calling functions, etc.) has an object that it uses to hold various names used in that context and their values; it's called a "binding object." The binding object for a context (I'm skipping some unrelated details here) has properties for each variable, function declaration, and a few other things like the arguments pseudo-array, the name of the function itself (referring back to the function), and such. The name of the properties are the names of the variables, declared functions, etc. That's why assigning to foo inside bar overwrites the reference to the foo function declared in bar, instead of assigning to the variable in the outer scope. foo is effectively a local variable in bar, even though it's not declared with var, because of the function declaration.
This has to do with a concept called hoisting. function foo is essentially just an alternative syntax for var foo = function .., so inside bar the name foo does not refer to the outer foo variable but to a locally defined foo. This foo is first a function, but later gets overwritten by 10.
Now, through hoisting the name foo is "reserved" and scoped at parse time, before the code executes. Essentially, it executes like this:
function bar(){
var foo = function () {};
foo = 10;
return;
}
Hence it does not overwrite the outer variable at all.

when should I put var in front of function in js?

<script type="text/javascript">
var output = function() {console.log('result')}
output();
</script>
If I changed to output = function() {console.log('result')}; it still shows the right result, so my question is:
what is the difference between them? when should I put var in front of function in js? is that the same principle as var in front of variable?
A function defined in a script tag is in the global scope (ie the window object in a browser context) so there is no difference in this case.
Inside a function block, however, is a different story. For example:
foo = function() {
var foo = 1;
console.log(foo);
}
foo(); // logs '1'
foo(); // logs '1'
But:
foo = function() {
foo = 1;
console.log(foo);
}
foo(); // logs '1'
foo(); // SyntaxError: Unexpected token function
Because foo wasn't defined locally, we overwrote the global object.
You're in the global window scope, so there's no difference.
It doesn't matter what the type of the variable is.
If this is declared in functions, then there is a difference:
function name(){
var a=1;
}
alert(a);
Here a will be undefined, as var declares the variable in the scope of the function.
As an excercise:
var a=2;
function name(){
var a=1;
}
name();
alert(a);
This alerts 2 instead of 1, since the middle var belongs in the scope of the function, which is separate from the global scope.
You can also modify global variables this way:
var a=2;
function name(){
a=3;
}
name();
alert(a);
Also compare this with let, which limits it's scope to the block instead: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
"Is that the same principle as var in front of variable?"
Yes. output is a variable.
So I would suggest you use var in front of it when you define it. You could eventually change its value without using var. As in:
var A=1;
A=2;
A=A+1;
Consider the "script" of the funcion as the "value" of that variable.
var F=function() {console.log('one')};
// change it later
F=function() {console.log('two')};
(not suggesting you do this, but to show you it is 100% a var)
You are actually assigning to the variable named "output" a value of "function() {console.log('result')}" not as a string but as a script that gets executed. Note the semicolon at the end like in var A=3;
Now "inside" output there is the code that executes console.log('result'). (more or less, just to explain).
As you usually do not change that same function later (you can, and sometimes it is done) I really suggest you use var in front of it every time you define a function like this, even in cases when it is not strictly necessary, just to be safe you do not override an existing function.
This is a bit different from defining the function as:
function output() {console.log('result')}
Here there is no = sign, no assignment, no semicolon at the end. This is not a variable assignment but a function "definition" although results are similar, and you can call output() in both cases, there are differences. The main one I think is that function definitions are examined before executing the script line by line, while with assignment you really need to have the assignment line processed before you can use the function. So this:
output();
function output() {console.log('result')}
works. While this:
output(); // nope! output not defined yet!
var output=function() {console.log('result')}
doesn't. Variables are assigned or changed when the assignment instruction is read and interpreted.
// here A is undefined, B() prints 'ok'
var A=function() {console.log('first')};
// here A() prints 'first', B() prints 'ok' as usual
A=function() {console.log('second')}; // change it
// here A() prints 'second', B() prints 'ok' as usual
function B() {console.log('ok')}
// same here A() prints 'second', B() prints 'ok'
Without var your variable will be declared as global variable which means it is available on other JS files too. In short If you declare a variable, without using var, the variable always becomes GLOBAL.
Generally there is no difference because you are in the global scope, but in ES5 there's a strict mode, which slightly changes the behavior of undeclared variables. In strict mode, assignment to an undeclared identifier (not putting var in front) is a ReferenceError.
For example:
"use strict";
myVariable = "foo"; // throws a ReferenceError
Function or not function, here's what MDN has to say about var:
The scope of a variable declared with var is the enclosing function or, for variables declared outside a function, the global scope (which is bound to the global object).
Using var outside a function is optional; assigning a value to an undeclared variable implicitly declares it as a global variable (it is now a property of the global object). The difference is that a declared variable is a non-configurable property of the global object while an undeclared is configurable.
And you could also read about the function statement here and the function operator here.
Cheers!

javascript scope of function declarations

The var keyword in javascript causes a variable to be stored in the local scope. Without var variables belong to the global scope. What about functions? It's clear what happens when functions are declared like variables
var foo = function() {...}
but what scope does
function foo() {...}
belong to?
EDIT:
I realized I didn't ask quite the right question so as a follow up. In the outer most nesting is there a difference between the above two declarations and the following declaration?
foo = function() {...}
It belongs to the current scope, always. For example:
// global scope
// foo is a global function
function foo() {
// bar is local to foo
function bar() {
}
}
Regarding your second question, this:
foo = function() {...}
is an anonymous function expression assigned to a global variable (unless you're running is strict mode, then foo would be undefined). The difference between that and function foo() {} is that the latter is a function declaration (versus a variable declaration, which is assigned an anonymous function expression).
You might be interested in this excellent article about function declarations and function expressions: Named function expressions demystified.
Function declarations are always local to the current scope, like a variable declared with the var keyword.
However, the difference is that if they are declared (instead of assigned to a variable) their definition is hoisted, so they will be usable everywhere in the scope even if the declaration comes in the end of the code. See also var functionName = function() {} vs function functionName() {}.
Noteworthy distinction taking implicit globals into account:
var foo = function() {
// Variables
var myVar1 = 42; // Local variable
myVar2 = 69; // Implicit global (no 'var')
// Functional Expressions
var myFn1 = function() { ... } // Local
myFn2 = function() { ... } // Implicit global
function sayHi() {
// I am a function declaration. Always local.
}
}
Hopefully that clarifies a little. Implicit globals are defined if you forget a var before your assignment. Its a dangerous hazard that applies to variable declarations and functional expressions.
Your first example (var foo = function() {...}) is called an anonymous function. It is dynamically declared at runtime, and doesn't follow the same rules as a normal function, but follows the rules of variables.

Trying to figure out how scope works

I'm trying to learn JS on codeacademy and I can't understand/get past this thing. Can someone please provide an answer and also an explanation of why is it so? Would deeply appreciate.
// This function tries to set foo to be the
// value specified.
function setFoo(val) {
// foo is declared in a function. It is not
// accessible outside of the function.
var foo = val;
}
setFoo(10);
// Now that we are outside the function, foo is
// not defined and the program will crash! Fix this
// by moving the declaration of foo outside of the
// function. Make sure that setFoo will still update
// the value of foo.
alert(foo);
You can see scope as a term meaning what variables you can reach at a specific "level" in the code. In JavaScript, these "levels" are defined by functions. Each function introduces a new level.
For example, take this sample code:
var a;
// you can access a at this level
function function1() {
var b;
// you can access a, b at this level
function function2() {
var c;
// you can access a, b, c at this level
}
}
So in your case, you should declare var foo; outside the function, preferably above it. Then you can set it inside setFoo with foo = val;. foo then refers to the one you declared in the level above setFoo.
foo is accessible both in setFoo and in the alert call that way; compare it with the above sample code (function1 is setFoo, a is foo and the alert call is in the top-most level. function2, b and c are not used in your case.).
// Create globale variable
// (You should not use globale variables!)
var foo;
// set value
function setFoo(val) {
foo = val;
}
setFoo(10);
// show value
alert(foo);
Just declare foo outside any function then it will be global:
var foo = null;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo);
Try it !
When you declare a variable in Javascript it is only visible to code that is in the same function as it is declared, or a function inernal to that function. Because foo is originally declared in the SetFoo function nothing outside of SetFoo is able to see it, so the call to alert fails as foo does not exist in the gloabl scope.
As the comments suggest, moving the declaration of foo out of the function and into the global scope (which you can think of as a catch-all function that contains everything) would allow you to use foo when calling alert.
var foo;
function setFoo(val) {
foo = val;
}
setFoo(10);
alert(foo); // No longer crashes
Every function in Javascript has it's own scope. That means that every variable you define there with the var keyword, will only be available within that function. That means that when you call setFoo(10), you create the variable foo, give it a value of five, after which it is immediately destroyed because it went out of scope.
There are multiple ways to solve this problem. The first would be to remove the var keyword. This would put foo in the global scope, which means that it's available everywhere. However, this is discouraged, you want to keep the global scope as uncluttered as possible, so that if you have javascript code provided by multiple people on the same page, they can't overwrite other people's variables. Another way to do it would be this:
function setFoo(val){
var foo = val;
alertfoo = function(){
alert(foo)
}
}
In this example, the only thing you're putting in the global scope is the alertfoo function, because you want that to be available everywhere. The alertfoo function is defined inside the setFoo function, this means that although foo should have gone out of scope after setfoo has been executed, it is kept in memory, because alertfoo has access to it.
This makes for some nice tricks. For example, let's say you're making a javascript library that will be included on other people's pages, you'll want to create a scope inside of which you can define variables, without polluting the global scope. The most common way to do this, is by declairing a self-executing function. This is a function which is executed immediately after being defined, it looks like this:
(function(){
//set variables you want to be global in your own code
var mainpage = document.getElementById('main');
//define functions you want to make available to other people in a way that puts them in the global scope
setMainElement = function(newmain){mainpage = newmain;}
})();
You can make this even better by making only one object global, and provide your interfae through the methods of that object, this way, you create a namespace with all the functions that your library contains. The next example uses an object literal to do this. In javascript, you can create an object by putting key/value pairs petween curly braces. the key/value pairs are properties of the object. for example:
(function(){
var privatevar = 10,otherprivate=20;
publicInterface = {
'addToPrivate': function(x){privatevar+=x;},
'getPrivate': function(){return private}
};
})();
Original code:
function setFoo(val) {
var foo = val;
}
setFoo(10);
alert(foo); // Crash!
Their advice to fix the crash:
Fix this by moving the declaration of foo outside of the function
I'm guessing you're confused as to what they mean by "outside of the function".
Try this edited code:
var foo = 5; // "var" declares the variable to be in this outer scope
function setFoo(val) {
foo = val; // but we can still access it in this inner scope...
}
setFoo(10);
alert(foo); // Displays a dialog box that says "10"
Variables defined in the function is valid only in the function
function setFoo(val) {
foo = val;
}
In JavaScript, new scopes are only created by functions

Categories

Resources