Lev*_*lho 6 javascript scope function
在以下代码中:
var greeting = "hi";
function changeGreeting() {
if (greeting == "hi") {
var greeting = "hello";
}
alert(greeting);
}
changeGreeting();?
Run Code Online (Sandbox Code Playgroud)
...... greeting
未定义.但是,如果我删除var
并更改changeGreeting()
为:
function changeGreeting() {
if (greeting == "hi") {
greeting = "hello";
}
alert(greeting);
}
Run Code Online (Sandbox Code Playgroud)
......我按预期"打招呼".
我永远不会在我的代码中重新声明这样的变量,但为什么会发生这种情况呢?
Ama*_*dan 27
JavaScript变量具有函数范围.因此,var greeting
函数内部的存在将声明一个局部greeting
变量,该变量在if
条件提及时将是未定义的:全局变量在函数内部不可见,被本地变量所掩盖.因此,if
不会发生,赋值hello
不会发生,变量仍未定义.
在第二个示例中,您始终使用全局变量,它不会被局部变量所掩盖(因为,var greeting
函数内部没有),并且事情按预期工作.
这很简单:JS将Variable声明提升到当前作用域的顶部,但是当然不会提升任何操作(包括赋值)(在同一范围内,参见第二种情况说明).所以你的片段被翻译成了
(function()
{
var currentSize;//undefined
if (currentSize == 'hi')//always false
{
currentSize = 'hello';//assignment that will never be
}
alert(currentSize);//alerts undefined, of course
}());
Run Code Online (Sandbox Code Playgroud)
通过省略var,继续进行范围扫描(检查在全局范围内声明的变量).遗憾的是,在这样做时,首次使用var的上下文丢失了(在分支内),并且分配也被提升了.隐含的全球被翻译为:
感谢上帝,这不是真的.我以为是,因为我在控制台中测试了几件似乎证实这一点的事情.在这种情况下,@ amadan是对的:你正在使用全局变量(greeting
当我发布这个时,在你的代码段中被错误地调用).我将保留下面的代码(更正它)以显示实际上隐含全局变量的内容,希望它有时可以帮助某人理解JS中的范围/范围扫描.
var currentSize = 'hello';
//well, actually implied globals can be deleted, so it's more like
Object.defineProperty(this,'currentSize',{value:undefined,
writable:true,
enumerable:true,
configurable:true});
(function()
{
if (currentSize == 'hi')//always false
{//this still doesn't get executed
currentSize = 'hello';//assignment that will never be
}
alert(currentSize);//alerts undefined
}());
Run Code Online (Sandbox Code Playgroud)