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

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

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

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

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

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 Not-allowed

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

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

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

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

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

阅读执行上下文:https://www.javascripttutorial.net/javascript-execution-context/ 然后阅读词法作用域以了解此行为。

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

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