The following works because function add()
is scoped to the nearest block:
try {
console.log("Success: ", add(1, 1));
} catch(e) {
console.log("ERROR: " + e);
}
function add(a, b){
return a + b;
}
_x000D_
The following does not work because the variable is called before a function value is assigned to the variable add
.
try {
console.log("Success: ", add(1, 1));
} catch(e) {
console.log("ERROR: " + e);
}
var add=function(a, b){
return a + b;
}
_x000D_
The above code is identical in functionality to the code below. Note that explicitly assigning add = undefined
is superfluous because simply doing var add;
is the exact same as var add=undefined
.
var add = undefined;
try {
console.log("Success: ", add(1, 1));
} catch(e) {
console.log("ERROR: " + e);
}
add = function(a, b){
return a + b;
}
_x000D_
The following does not work because var add=
begins an expression and causes the following function add()
to be an expression instead of a block. Named functions are only visible to themselves and their surrounding block. As function add()
is an expression here, it has no surrounding block, so it is only visible to itself.
try {
console.log("Success: ", add(1, 1));
} catch(e) {
console.log("ERROR: " + e);
}
var add=function add(a, b){
return a + b;
}
_x000D_
The name of a function function thefuncname(){}
is thefuncname when it is declared this way.
function foobar(a, b){}
console.log(foobar.name);
_x000D_
var a = function foobar(){};
console.log(a.name);
_x000D_
Otherwise, if a function is declared as function(){}
, the function.name is the first variable used to store the function.
var a = function(){};
var b = (function(){ return function(){} });
console.log(a.name);
console.log(b.name);
_x000D_
If there are no variables set to the function, then the functions name is the empty string (""
).
console.log((function(){}).name === "");
_x000D_
Lastly, while the variable the function is assigned to initially sets the name, successive variables set to the function do not change the name.
var a = function(){};
var b = a;
var c = b;
console.log(a.name);
console.log(b.name);
console.log(c.name);
_x000D_
In Google's V8 and Firefox's Spidermonkey there might be a few microsecond JIST compilation difference, but ultimately the result is the exact same. To prove this, let's examine the efficiency of JSPerf at microbenchmarks by comparing the speed of two blank code snippets. The JSPerf tests are found here. And, the jsben.ch testsare found here. As you can see, there is a noticable difference when there should be none. If you are really a performance freak like me, then it might be more worth your while trying to reduce the number of variables and functions in the scope and especially eliminating polymorphism (such as using the same variable to store two different types).
When you use the var
keyword to declare a variable, you can then reassign a different value to the variable like so.
(function(){
"use strict";
var foobar = function(){}; // initial value
try {
foobar = "Hello World!"; // new value
console.log("[no error]");
} catch(error) {
console.log("ERROR: " + error.message);
}
console.log(foobar, window.foobar);
})();
_x000D_
However, when we use the const-statement, the variable reference becomes immutable. This means that we cannot assign a new value to the variable. Please note, however, that this does not make the contents of the variable immutable: if you do const arr = []
, then you can still do arr[10] = "example"
. Only doing something like arr = "new value"
or arr = []
would throw an error as seen below.
(function(){
"use strict";
const foobar = function(){}; // initial value
try {
foobar = "Hello World!"; // new value
console.log("[no error]");
} catch(error) {
console.log("ERROR: " + error.message);
}
console.log(foobar, window.foobar);
})();
_x000D_
Interestingly, if we declare the variable as function funcName(){}
, then the immutability of the variable is the same as declaring it with var
.
(function(){
"use strict";
function foobar(){}; // initial value
try {
foobar = "Hello World!"; // new value
console.log("[no error]");
} catch(error) {
console.log("ERROR: " + error.message);
}
console.log(foobar, window.foobar);
})();
_x000D_
The "nearest block" is the nearest "function," (including asynchronous functions, generator functions, and asynchronous generator functions). However, interestingly, a function functionName() {}
behaves like a var functionName = function() {}
when in a non-closure block to items outside said closure. Observe.
var add=function(){}
try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}');
}
} catch(e) {
console.log("Is a block");
}
var add=function(a, b){return a + b}
_x000D_
function add(){}
try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}')
}
} catch(e) {
console.log("Is a block");
}
function add(a, b){
return a + b;
}
_x000D_
try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}')
}
} catch(e) {
console.log("Is a block");
}
(function () {
function add(a, b){
return a + b;
}
})();
_x000D_
if
, else
, for
, while
, try
/catch
/finally
, switch
, do
/while
, with
)try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}')
}
} catch(e) {
console.log("Is a block");
}
{
function add(a, b){
return a + b;
}
}
_x000D_
var add=function()
try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}')
}
} catch(e) {
console.log("Is a block");
}
(() => {
var add=function(a, b){
return a + b;
}
})();
_x000D_
function add()
try {
// typeof will simply return "undefined" if the variable does not exist
if (typeof add !== "undefined") {
add(1, 1); // just to prove it
console.log("Not a block");
}else if(add===undefined){ // this throws an exception if add doesn't exist
console.log('Behaves like var add=function(a,b){return a+b}')
}
} catch(e) {
console.log("Is a block");
}
(() => {
function add(a, b){
return a + b;
}
})();
_x000D_