Javascripts variables are local

var name = "Michael";
// the blocks in this if statement do not create a local context for the name variable​
​if (name) {
	name = "barack"; // this name is the global name variable and it is being changed to "Jack" here​
	console.log (name); // barack: still the global variable​
}
​
​// Here, the name variable is the same global name variable, but it was changed in the if statement​
console.log (name); // Barack

But the above doesn’t look like to be a local variable but seems to be behaving like a global variable.

can we please discuss more about the scope of the variable here?

JavaScript variables have function scope. Use let and const if you want them to be block scope.

I learned the above two today, but I am confused with what I saw and posted above.

can you summarize the scope of Javascripts variables?

Why not go and read about it instead?

2 Likes

I don’t blame you for being confused. The code has “Michael” and “barack” values being assigned, yet the comments refer to “Jack” which is not in the code.

2 Likes

JavaScript has global and local variables.

var glob = "Global variable";

function someFunc() {
  var local = "Local variable";
  console.log("Inside function");
  console.log("Global variable is", glob);
  console.log("Local variable is", local);
}

someFunc();

console.log("Outside function");
console.log("Global variable is", glob);
console.log("Local variable is", local); // Uncaught reference error

The local variable inside the function is not visible when outside of the function.

There is also a technique called closure, where a function retains knowledge of the variables from its own parent scope.

function parentFunc() {
    var localVar = "local variable";
    return function innerFunc() {
        return localVar;
    };
}

var inner = parentFunc();
console.log("Local variable visible from inner function",  inner());
1 Like

Fixed!

Nice article.

I have some confusion understanding this:

let is the descendant of var in modern JavaScript. Its scope is not only limited to the enclosing function, but also to its enclosing block statement. A block statement is everything inside { and }, (e.g. an if condition or loop).

Should we conclude:

  1. It is accessible anywhere in the block
  2. It is accessible anywhere in the function.

I think the above two points can also be termed as closure. Right?

or

Am I still not spot on?

Yes.

No.

Closure is when a returned function retains knowledge of its parents scope.

You can read more about closure at JavaScript Closures Demystified

1 Like

What I learned yesterday I think it is not wise to declare variables globally, but look here in the above-mentioned code many variables are declared outside the functions. Is it ok? or there is a better way? or there was no other way?

In that example, addHD is required outside, but accItem can (and should) certainly go inside of the function.

1 Like

Sir, Can you please help me why? When did you say it is required outside?

On what coding logic it is mandatory to declare it outside?

Because, addHD is not used by the function, and is required by the for loop that’s outside of the function.

1 Like

If your interest is instead about why it has to be global, it doesn’t have to be global at all.

A common practice is to protect the global namespace by placing all of your code inside of an IIFE (immediately invoked function expression) so that you can define whatever you like in there, without them becoming global variables.

(function iife() {
  // code in here
}());

You mean this:

(function iife() {
  	var accItem = document.getElementsByClassName('accordionItem');
    var accHD = document.getElementsByClassName('accordionItemHeading');
    for (i = 0; i < accHD.length; i++) {
        accHD[i].addEventListener('click', toggleItem, false);
    }
    function toggleItem() {
        var itemClass = this.parentNode.className;
        for (i = 0; i < accItem.length; i++) {
            accItem[i].className = 'accordionItem close';
        }
        if (itemClass == 'accordionItem close') {
            this.parentNode.className = 'accordionItem open';
        }
    }
}());
1 Like

Now the variable in discussions are not global, but have limited or local scope within the block?

Secondly, when we are enveloping them within such functions we can also use strict. Right sir?

thirdly, when we have enveloped them in a function the closure has come into picture right sir?

Yes, yes, and no.

There is only closure when a function is returned out of its parent function. That returned function retains knowledge of its parents scope, via a technique called closure.

1 Like

1 Like

I used it like this and the script stopped working →

( function iife() {
		"use strict";
		var accItem = document.getElementsByClassName('accordionItem');
	    var accHD = document.getElementsByClassName('accordionItemHeading');
	    for (i = 0; i < accHD.length; i++) {
	        accHD[i].addEventListener('click', toggleItem, false);
	    }
	    function toggleItem() {
	        var itemClass = this.parentNode.className;
	        for (i = 0; i < accItem.length; i++) {
	            accItem[i].className = 'accordionItem close';
	        }
	        if (itemClass == 'accordionItem close') {
	            this.parentNode.className = 'accordionItem open';
	        }
	    }
}());

accordion.zip (2.0 KB)

Uncaught ReferenceError: i is not defined
    at custom.js:5
    at custom.js:18

I defined i with let and it worked.

1 Like