JavaScript: 在函数中初始化全局变量
JavaScript: initialize global variable in function
我有一个问题,对于您有经验的 JavaScript 程序员(我更像是一个 backend/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();
输出为:
undefined
Java
我明白 运行 这段代码是可能的,因为 JavaScript 不是 编译的 ,它是在 运行 时间内解释的(这不会在例如 C++ 中编译)。但到底为什么这段代码有效呢?例如。为什么记录 undefined
而不是 "JavaScript"
,这在涉及范围规则时是显而易见的选择,例如C++。而且,第二条日志怎么打印出来"Java",不也是undefined
吗?
这是幕后发生的事情:
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。
不要使用 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
因为那时局部变量是未定义的。
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();
这种现象被许多人称为"hoisting",但他们完全不是"lifted up"。这就是编译器如何运行您的代码。
解决您的问题:
如果您打算将范围内的 skill
替换为 Java
,则在对其进行任何操作之前将声明和定义移至顶部。
如果您打算替换全局 skill
,则删除函数内 skill
上的 var
。
此功能在 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();
叫做scoping and hoisting.在javascript中有两种范围,它们是全局范围和函数scope.Injavascript 函数创建自己的作用域。
所以你的代码等价于下面的代码:
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()
里面的第二个技能变量。它有自己的 scope.It 调用函数 scope.And 在这个函数中定义的所有变量都被提升到它的包装函数范围的顶部, 不在全局范围.
所以当你在 pritSkill()
中 console.log() variable skill
时,首先它会在函数 scope.If 中查找它在那里找不到它然后它会查找 up 在范围 chain.In 你的情况下它发现技能提升在函数的顶部但它没有分配任何 value.So first console.log() 打印未定义。
在第二个 console.log()
中,它找到分配给技能的 value.So 它打印分配给技能的值
在你的代码中,如果你想初始化你的全局 skill
变量,你不能声明任何其他与全局同名的变量 one.Declaration 由于提升为,订单不算数我已经提到 above.Here 是应该如何编写代码。
注意:在代码中到处声明全局变量被认为是错误的编码习惯
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();
我有一个问题,对于您有经验的 JavaScript 程序员(我更像是一个 backend/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();
输出为:
undefined
Java
我明白 运行 这段代码是可能的,因为 JavaScript 不是 编译的 ,它是在 运行 时间内解释的(这不会在例如 C++ 中编译)。但到底为什么这段代码有效呢?例如。为什么记录 undefined
而不是 "JavaScript"
,这在涉及范围规则时是显而易见的选择,例如C++。而且,第二条日志怎么打印出来"Java",不也是undefined
吗?
这是幕后发生的事情:
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。
不要使用 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
因为那时局部变量是未定义的。
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();
这种现象被许多人称为"hoisting",但他们完全不是"lifted up"。这就是编译器如何运行您的代码。
解决您的问题:
如果您打算将范围内的
skill
替换为Java
,则在对其进行任何操作之前将声明和定义移至顶部。如果您打算替换全局
skill
,则删除函数内skill
上的var
。
此功能在 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();
叫做scoping and hoisting.在javascript中有两种范围,它们是全局范围和函数scope.Injavascript 函数创建自己的作用域。
所以你的代码等价于下面的代码:
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()
里面的第二个技能变量。它有自己的 scope.It 调用函数 scope.And 在这个函数中定义的所有变量都被提升到它的包装函数范围的顶部, 不在全局范围.
所以当你在 pritSkill()
中 console.log() variable skill
时,首先它会在函数 scope.If 中查找它在那里找不到它然后它会查找 up 在范围 chain.In 你的情况下它发现技能提升在函数的顶部但它没有分配任何 value.So first console.log() 打印未定义。
在第二个 console.log()
中,它找到分配给技能的 value.So 它打印分配给技能的值
在你的代码中,如果你想初始化你的全局 skill
变量,你不能声明任何其他与全局同名的变量 one.Declaration 由于提升为,订单不算数我已经提到 above.Here 是应该如何编写代码。
注意:在代码中到处声明全局变量被认为是错误的编码习惯
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();