这里的变量的行为是什么,即闭包。输出未定义,我不明白

What is the behavior of the variables here, i.e. closure. The output is undefined which I don't understand

提问人:Mridul 提问时间:9/8/2021 最后编辑:Mridul 更新时间:9/8/2021 访问量:77

问:

这里的变量的行为是什么,即闭包。输出是“未定义”的,我不明白。

var x = 21; 
var test = function () { 
    console.log(x); // output: undefined 
    var x = 20; 
}; 
test();
JavaScript 节点 .js 闭包

评论

0赞 jabaa 9/8/2021
变量声明被提升到函数的顶部,但变量初始化不会被提升: developer.mozilla.org/en-US/docs/Glossary/Hoisting:“只有声明被提升 JavaScript 只提升声明,而不是初始化。如果在代码中使用变量,然后声明和初始化,则使用该变量时的值将是其默认初始化(对于使用 var 声明的变量未定义,否则未初始化)。
2赞 Andreas 9/8/2021
test实际上看起来像这样:function() { var x; console.log(x); x = 20; }
0赞 Andreas 9/8/2021
如果你使用(现在真的只是一个遗产和),你会得到.letvarletconstReferenceError: can't access lexical declaration 'x' before initialization

答:

-2赞 Abdullah Shokr 9/8/2021 #1

你忘了把参数放在函数测试中 代码应该是这样的:-

var x = 21; 
var test = function (x) { //here u should put parameter "x"
    console.log(x); // The output from calling method
    var x = 20; //last "x"
    //if u want to get the value of last "x" should call 
    console.log(x); // the value of of last "x"
}; 
test(x); //here u should put parameter "x"

在代码中,我解释了每一件事 😉

笔记:- 使用 let 定义的变量不能重新声明。 使用 let 定义的变量必须在使用前声明。 使用 let 定义的变量具有块作用域。 在另一个块中,允许使用 let 重新声明变量 但使用 var 不允许

评论

0赞 lqc 9/8/2021
@jfriend00 你错了。函数体中的声明不会使参数黯然失色。它实际上什么也没做:ideone.com/Ege7fuvar
0赞 Community 9/8/2021
请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
2赞 Arushi Gupta 9/8/2021 #2

Javascript 最初会创建一个全局执行上下文,每次在调用堆栈上推送函数时都会创建一个新的执行上下文。这分两个阶段进行:它首先创建一个变量环境,其中每个变量都存储在键值对 variable_name: undefined 中(而函数与函数定义一起存储)。然后它开始逐行执行代码。

如果我要演练这个例子: 全局执行上下文: 变量环境 { x:未定义, test:测试的函数定义 }

然后逐行执行代码,21 替换 x 值的 undefined。现在调用 test,因此创建了一个新的执行上下文

测试的执行上下文: { x:未定义 }

现在,当它开始执行代码时,它会在此执行上下文中查找 x,并看到该值未定义,并记录它。 如果 x 不存在于测试中,它将查看函数的父级执行上下文,这恰好是全局执行上下文,并且会记录 21。

阅读执行上下文: https://www.javascripttutorial.net/javascript-execution-context/ 然后阅读词汇范围以了解此行为。

1赞 Owen Young 9/8/2021 #3

Javascript 引擎将像这样解释你的代码:

var x = 21; 
var test = function () {
    var x;
    console.log(x); // output: undefined 
    x = 20; 
}; 
test();