为什么定义的全局变量是未定义的?

IT技术 javascript global-variables local-variables hoisting
2021-01-15 02:29:06

我这里有一个简单的函数和一个全局变量。

为什么是myname undefined而不是字符串"global"

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

不能引用在该函数范围之外定义的外部变量吗?在这个全局变量中......

我该如何解决这个问题,这样我就不会undefined从全局变量中获得 a

3个回答

你刚刚偶然发现了一个叫做提升的 js“特性”

var myname = "global"; // global variable
function func() {
    alert(myname); // "undefined"
    var myname = "local";
    alert(myname); // "local"
}
func();

在这段代码中定义func编译器时会查看函数体。它看到您正在声明一个名为myname.

的Javascript升降机变量和函数声明,该声明移动到函数的顶部。

由于提升你的代码被重写为以下内容。

var myname = "global"; // global variable
function func() {
   var myname; //declare local variable and assign it undefined
   alert(myname); // "undefined"
   myname = "local"; // assign local var myname to "local"
   alert(myname); // "local"
}
func();

这“覆盖”了全局变量。如果要访问函数范围内的全局变量,请使用this关键字。

var myname = "global"; // global variable
function func() {
    var myname = "local";
    alert(this.myname); // "global"
    alert(myname); // "local"
}
func();

请注意,这仅适用于调用函数而不是方法或构造函数,因为this关键字会根据您调用函数的方式更改其绑定的内容。

编辑:为了完整性

如果您想在任何上下文中访问全局变量而不管函数类型如何,请声明一个按照惯例您永远不会覆盖的全局变量。

var global = this; // in global scope.
var myname = "global";
var obj = {f: function () {
    var myname = "local";
    console.log(global.myname);
}};
obj.f(); // "global"

请注意,这是在方法位置,this关键字直接引用 obj,因此没有定义 myname。

这是正确答案,我错了
2021-03-18 02:29:06
如果这是在浏览器中,您可以使用该window变量而不是您的global变量。
2021-03-21 02:29:06
感谢您的解释。这说得通。不过我有一个问题。为什么声明与函数第三行的赋值分开?
2021-03-27 02:29:06
@Preza8 JS 是在一周内设计的。我认为考虑到这一点非常好。
2021-03-31 02:29:06
@codingpuss 提升不会移动到分配发生的地方。它只复制函数中需要的变量并在顶部声明它们。
2021-04-08 02:29:06

在函数内部,您声明var myname = "local". 即使您在方法的中间执行此操作,该变量也具有函数作用域,因此它属于整个函数,甚至是其上方的代码。

所以局部变量的值在那行之前是未定义的,之后有一个值,但没有人接触全局变量。

我不认为你的这部分答案是准确的:“所以局部变量的值在那行之前是未定义的......”。var 语句在 javascript(提升)中移动到顶部,因此它在其分数中的任何其他代码之前执行(在本例中为函数)
2021-04-07 02:29:06
作为一名新程序员,无论我阅读了多少这些答案,我都无法弄清楚这个问题的解决方案。问题是我假设每次我想修改一个变量时,我都必须以var(如var myVariable = 1;, var myVariable = myVariable + 3;开头,而实际上,您应该只var在第一次初始化变量时输入。在此之后的所有其他时间,您只需要以变量名称开始行并删除var(如var myVariable = 1;, myVariable = myVariable + 3;)。(否则会出现这样的问题)
2021-04-11 02:29:06

第一个警报未定义的原因是因为您global在函数中重新声明为它下面的局部变量。在 javascript 中,这意味着从函数的顶部开始,它被认为是局部变量。

它下面的那个有效,因为就在警报之上,你给了它一个值。