JavaScript:在函数中初始化全局变量

时间:2015-01-17 12:53:26

标签: javascript scope

对于经验丰富的JavaScript程序员(我更像是后端/ DB开发人员),我有一个明显的问题。所以,如果这太简单了,请耐心等待我!

我有这段代码:

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();

输出结果为:

  

未定义
  爪哇

我知道可以运行此代码,因为JavaScript不是编译的,它在运行时被解释(这不会在例如C ++中编译)。但是为什么这个代码在运行呢?例如。为什么undefined被记录而不是"JavaScript",这对于例如范围界定规则来说是明显的选择。 C ++。而且,为什么第二个日志打印“Java”,那也不是undefined

5 个答案:

答案 0 :(得分:2)

JavaScript分两次解析。首先,它找到所有函数和变量声明,然后执行代码。这意味着对于编译器,您的代码如下所示:

// declaration
var skill = undefined; 

// declaration
function printSkill() {

    // declaration
    var skill = undefined;

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

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

这种现象被许多人称为“悬挂”,但它们完全没有被“提升”。这就是编译器如何运行代码。

解决您的问题:

  • 如果您打算将范围内的skill替换为Java,请先将声明和定义移到顶部,然后再对其进行操作。

  • 如果您打算替换全局skill,请删除该功能内var上的skill

答案 1 :(得分:1)

它被称为scoping and hoisting. javascript中有 两种 范围,它们是 全球 范围和 功能 范围。在javascript函数中创建自己的范围。

所以您的代码等同于以下内容:

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();

现在来到printSkill()内的第二个技能变量。它有自己的范围。它被称为函数范围。此函数中定义的所有变量都在其包装函数范围的顶部提升, 不在全局范围

所以当你在variable skill里面的console.log()pritSkill()时,它首先会查看函数范围。如果找不到它那么它会看起来 up 。在您的情况下,它会在函数顶部找到提升的技能,但未分配任何值。所以 第一个 控制台。 log()打印undefined。

在第二个console.log()中,它找到分配了一个值的技能。因此它会打印分配给技能的值


在您的代码中,如果您要初始化全局skill变量,则不能声明任何其他变量与全局变量具有相同的名称。由于我提到的提升,声明顺序不计算在内上面。这是代码应该如何编写。

注意:在代码中声明全局变量被认为是错误的编码实践

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();

答案 2 :(得分:0)

这是幕后发生的事情:

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();

这称为变量hoisting

答案 3 :(得分:0)

不要使用var关键字来创建全局范围:

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();

问题在于宣布它:

var skill = "Java";

在函数内部,您将此skill变量的得分作为函数范围的本地。因此,在函数内部,第一个print语句为您提供undefined,因为那时局部变量是未定义的。

答案 4 :(得分:0)

此功能在javascript中称为提升 当您的代码运行时,您的代码将变为:

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();