简体   繁体   中英

JavaScript: initialize global variable in function

I have question which may be obvious for you experienced JavaScript programmers (I'm more of a backend/DB developer). So, if this is too simple please bear with me!

I have this code:

var skill = "JavaScript";

function printSkill() {
    console.log(skill); // <-- This prints undefined
    var skill = "Java"; // <-- How can this possibly work?
    console.log(skill); // <-- This prints "Java"
}

printSkill();

The output is:

undefined
Java

I understand that it is possible to run this code since JavaScript is not compiled , it is interpreted in runtime (this would not compile in eg C++). But why on earth does this code work? Eg why is undefined logged instead of "JavaScript" which would be the obvious choice when it comes to scoping rules for eg C++. And, how come the second log prints "Java", wouldn't that also be undefined ?

JavaScript is parsed in two passes. First it finds all function and variable declarations, then executes the code. This means to the compiler, your code looks like this:

// declaration
var skill = undefined; 

// declaration
function printSkill() {

    // declaration
    var skill = undefined;

    // execution
    console.log(skill);
    skill = "Java";
    console.log(skill);
}

// execution
skill = "JavaScript";
printSkill();

This phenomenon is called by many as "hoisting", but they're totally not "lifted up". It's just how the compiler runs through your code.

To solve your issue:

  • If you meant to replace skill inside the scope to Java , then move the declaration and definition on top before doing anything with it.

  • If you meant to replace the global skill , then remove var on the skill inside the function.

It's called scoping and hoisting. There are two types of scope in javascript, they are Global scope and Function scope.In javascript functions create their own scope.

So your code is equivalent to the following :

var skill;  // hoisted at the top of global scope and undefined

skill = "JavaScript";  // value assigned to it

function printSkill() {

    var skill;   //--> Hoisted at the top of function's scope and it is undefined 

    console.log(skill); // <-- So this prints undefined

     skill = "Java"; // <-- here it is assigned a value "java"

    console.log(skill); // <-- This prints "Java"

}

printSkill();

Now come to the second skill variable inside printSkill() . It has it's own scope.It's called function scope.And all the variables which is defined inside this function is hoisted at the top of it's wrapper function's scope , not on global scope .

So when you console.log() variable skill inside pritSkill() first it looks in functions scope.If it doesn't find it there then it will look up in the scope chain.In your case it finds skill hoisted at the top of the function but it is not assigned any value.So first console.log() prints undefined.

In second console.log() it finds skill assigned a value.So it prints the value which is assigned to skill


In your code, if you want to initialize your global skill variable, you can not declare any other variable having same name as the global one.Declaration order doesn't count due to hoisting as I've mentioned above.Here is how the code should be written.

Note : declaring global variables here and there in your code is considered bad coding practice

var skill = "JavaScript";

function printSkill() {
    console.log(skill); // <-- This prints "javascript"
    skill = "Java"; // <-- assign value "Java" to global "skill" variable
    console.log(skill); // <-- This prints "Java"
}

printSkill();

This is what happens behind the scenes:

var skill = "JavaScript";

function printSkill() {
    var skill; // skill is undefined and scoped to printSkill,
               // it is no longer the same `skill` variable
    console.log(skill); // <-- This prints undefined
    skill = "Java"; // <-- How can this possibly work?
    console.log(skill); // <-- This prints "Java"
}

printSkill();

This is called variable hoisting .

Don't use var keyword to create global scope:

var skill = "JavaScript"; // global variable

function printSkill() {
    console.log(skill); // <-- This prints JavaScript
    skill = "Java"; // remove "var" to keep it global
    console.log(skill); // <-- This prints "Java"
}

printSkill();

Problem is by that declaring it:

var skill = "Java";

inside the function you're making this skill variable's score local to function scope. Hence inside the function first print statement gives you undefined since at that time local variable is undefined.

this feature called Hoisting in javascript when your code is running,your code will become:

var skill; function printSkill() {
    var skill;
    console.log(skill); // <-- This prints undefined
    var skill = "Java"; // <-- How can this possibly work?
    console.log(skill); // <-- This prints "Java" }

var skill = "JavaScript";
printSkill();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM