If you're in a hurry, it's best to see examples of scope visibility in Bacco's response:)
The main difference is of scope visibility, which Bacco has demonstrated in response from him examples. To understand how this works, you need to understand how it works what is called variable hoisting in JavaScript. If you think variables and functions are created at the point of the code they are declared in, you are wrong.
First of all, a brief consideration of how JavaScript works: there is a global scope, and there are function scopes. Each function creates a new scope. If there are nested functions, the inner ones see the variables of the outer ones, but not the other. The mgibsonbr answer about closures illustrates this well:
function x(a1) { // "x" tem acesso a "a"
var a2;
function y(b1) { // "y" tem acesso a "a" e "b"
var b2;
function z(c1) { // "z" tem acesso a "a", "b", e "c"
var c2;
Each time a function is invoked, a execution context is created for it, where the variables it defines are stored. In the case of the x
function above, the execution context contains references to a1
, a2
and y
(respectively, a parameter, a variable, and a function). Now, consider the following example:
function x(a) {
var a = "foo";
function a() {
// nada
}
alert(typeof a);
}
x(10);
What will happen on the alert? The type "number"
of the argument passed, the type "string"
of the variable, or the type "function"
of the function? Answer: "string"
( test yourself ). At this time, you scratch your head and say:
But how come ?! The function was declared after of the variable! You should give "function"!
Yes, it makes sense what you thought. It turns out that the algorithm responsible for the binding of the arguments, variables, and functions to the execution context does this in a very specific order, which is as follows:
Arguments
Function statements
Variables
If there are equal names between arguments, function declarations, and variables, they will be overwritten in that order. In our example, a
starts as the number 10
, then it is overwritten by the function, and finally it is overwritten by the variable (before the assignment). This all happens before any code is executed in the function, including assigning the value "foo"
to a
. In code, what happens is something like this:
function x(a) {
function a() {
// nada
}
var a; // undefined, por enquanto
a = "foo";
alert(typeof a); // "string"
}
x(10);
Notice that the variable declaration is separate from the assignment. It is said that the statement is "raised" or "hoisted" ( hoisted ) to the top of the scope. See this example:
function f() {
var a = 10;
var b = 10;
function c() {}
var d = function() {};
}
This is actually interpreted like this:
function f() {
function c() {}
var a = undefined, b = undefined, d = undefined;
a = 10;
b = 10;
d = function() {};
}
Look at that thing! The c
function is available from the beginning, but function d is not! This is because c
was created via function declaration , while the function in d
was created via function expression (declarations always have names, and always start with function
as the first thing on the line, disregarding the spaces). If we want to invoke c
before the line where it is declared, no problem, since hoisting makes it already available:
function f() {
var a = 10;
var b = 10;
c(); // SEM PROBLEMAS!
function c() {}
var d = function() {};
}
The same is not true for d
: there will only be a function in d
after the line where the assignment is made. See:
function f() {
var a = 10;
var b = 10;
d(); // TypeError! Estamos tentando chamar undefined como função
function c() {}
var d = function() {};
}
Therefore, answering the question: var name = function()
and function name()
are different because the first is a variable declaration, which is assigned a function, while the second is a function declaration. This has consequences as to when the function will be available to be invoked.