对于经验丰富的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
?
答案 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 范围链中的em> 。在您的情况下,它会在函数顶部找到提升的技能,但未分配任何值。所以 第一个 控制台。 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();