为什么这个变量在函数中没有定义?(复制)

时间:2022-04-11 20:26:00

This question already has an answer here:

这个问题已经有了答案:

I have the sample code:

我有样本代码:

var t = 20;
function test () {
  console.log(t);
    var t = 100;
}
test();

The result will be undefined. I thought t was global variable, so why, when I log it, is it undefined?

结果将是未定义的。我认为t是全局变量,那么为什么,当我记录它时,它没有定义?

3 个解决方案

#1


5  

The scope of a variable is the reason why you're seeing this. From the MDN documentation on var:

变量的范围就是你看到这个的原因。来自关于var的MDN文档:

var hoisting

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

因为在执行任何代码之前都要处理变量声明(和一般的声明),所以在代码中的任何地方声明变量就等同于在顶部声明变量。这也意味着一个变量可以在声明之前被使用。这种行为称为“提升”,因为似乎将变量声明移动到函数或全局代码的顶部。

Variables in JavaScript are function-scoped, meaning they only exist in the function. Since variable declarations are processed before any execution of code, they are declared are the beginning of the enclosing function-scope. This "pre-processing" is called "hoisting", as the declaration is hoisted up to the beginning of the enclosing function-scope. Since you redeclare t inside the function, it's declared at the beginning of the function (because variables are function-scoped) and is equivalent to this:

JavaScript中的变量具有函数作用域,这意味着它们只存在于函数中。由于在执行任何代码之前都要处理变量声明,所以声明它们是封闭的功能范围的开始。这种“预处理”称为“提升”,因为声明被提升到封装功能范围的开始。由于在函数中重新声明t,它在函数的开头声明(因为变量是函数作用域的),并且等价于:

var t = 20;
function test () {
    var t;
    console.log(t);
    t = 100;
}
test();

Since t is never given a value before you assign it after the logging, it's undefined. The solution is to remove the var redeclaration. Thus, no declaration of a variable is seen in the function and nothing is hoisted.

由于t在您在日志记录之后赋值之前从来没有被赋值,所以它是未定义的。解决方案是删除var重新声明。因此,在函数中看不到变量的声明,也没有提升。


Note that this hoisting procedure is the same reason why you can use function declarations before they're defined:

注意,这个提升过程与在定义函数声明之前使用函数声明的原因相同:

foo(); //logs "foo called!"

function foo() {
    console.log("foo called!");
}

Function declarations (and only declarations) are hoisted like variables (but instead, the whole declaration is hoisted, not just the name). Thus, the function is declared before any execution happens, and when the code is run, foo is called as it's already declared.

函数声明(和仅声明)像变量一样挂起(相反,整个声明被挂起,而不仅仅是名称)。因此,函数在执行之前被声明,当代码运行时,将调用foo,因为它已经声明。

#2


1  

From MDN:

中数:

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

因为在执行任何代码之前都要处理变量声明(和一般的声明),所以在代码中的任何地方声明变量就等同于在顶部声明变量。这也意味着一个变量可以在声明之前被使用。这种行为称为“提升”,因为似乎将变量声明移动到函数或全局代码的顶部。

What this means is that your function's declaration of a new t variable is effectively performed at the opening of the function. This immediately obscures the "global" t variable with the local one. However, the line of code which sets a value to that new t variable doesn't execute until after you log to the console. So the default value is undefined.

这意味着函数的新t变量声明在函数开始时被有效地执行。这立即模糊了“全局变量”与本地变量的关系。然而,为新t变量设置值的代码行直到您登录到控制台之后才执行。所以默认值没有定义。

Perhaps not the most intuitive feature of JavaScript in this example, I'll admit. But at the same time it highlights the importance of clarity in your code. Having two variables of the same name even attempt to be accessible in the same scope is a potential source for bugs. It would be better to give them different names.

我承认,在这个示例中,JavaScript可能不是最直观的特性。但与此同时,它强调了代码中清晰性的重要性。拥有两个相同名称的变量甚至尝试在相同的范围内访问都是bug的潜在来源。最好给他们起不同的名字。

#3


0  

t is both global and local.

t既是全局的,也是局部的。

When you are inside a function there is something called scope. This means you can declare variables with the same names as global ones and they will actually be completely different. Now notice where you place console.log(). If you did not decalre a variable t inside your function you would log 20 however you did so the function is concerned with the function's t. But you are logging before the t was declared!

当你在一个函数中,有一个叫做作用域的东西。这意味着您可以声明与全局变量名称相同的变量,它们实际上是完全不同的。现在请注意console.log()的位置。如果你没有在你的函数中去除一个变量t,你将会记录20,不管你怎么做,所以这个函数与函数的t有关。

var t = 20;
function test () {    
    console.log(t);
}
test();

var t = 20;
function test () {
    console.log(t);
    var t = 100;
}
test();

Your code is equivalent to: (the var is moved to the top without being defined. Something called hoisting.)

您的代码相当于:(var被移动到顶部而没有定义。所谓的提升)。

var t = 20;
function test () {
    var t;
    t = 100;
     console.log(t);
}
test();

#1


5  

The scope of a variable is the reason why you're seeing this. From the MDN documentation on var:

变量的范围就是你看到这个的原因。来自关于var的MDN文档:

var hoisting

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

因为在执行任何代码之前都要处理变量声明(和一般的声明),所以在代码中的任何地方声明变量就等同于在顶部声明变量。这也意味着一个变量可以在声明之前被使用。这种行为称为“提升”,因为似乎将变量声明移动到函数或全局代码的顶部。

Variables in JavaScript are function-scoped, meaning they only exist in the function. Since variable declarations are processed before any execution of code, they are declared are the beginning of the enclosing function-scope. This "pre-processing" is called "hoisting", as the declaration is hoisted up to the beginning of the enclosing function-scope. Since you redeclare t inside the function, it's declared at the beginning of the function (because variables are function-scoped) and is equivalent to this:

JavaScript中的变量具有函数作用域,这意味着它们只存在于函数中。由于在执行任何代码之前都要处理变量声明,所以声明它们是封闭的功能范围的开始。这种“预处理”称为“提升”,因为声明被提升到封装功能范围的开始。由于在函数中重新声明t,它在函数的开头声明(因为变量是函数作用域的),并且等价于:

var t = 20;
function test () {
    var t;
    console.log(t);
    t = 100;
}
test();

Since t is never given a value before you assign it after the logging, it's undefined. The solution is to remove the var redeclaration. Thus, no declaration of a variable is seen in the function and nothing is hoisted.

由于t在您在日志记录之后赋值之前从来没有被赋值,所以它是未定义的。解决方案是删除var重新声明。因此,在函数中看不到变量的声明,也没有提升。


Note that this hoisting procedure is the same reason why you can use function declarations before they're defined:

注意,这个提升过程与在定义函数声明之前使用函数声明的原因相同:

foo(); //logs "foo called!"

function foo() {
    console.log("foo called!");
}

Function declarations (and only declarations) are hoisted like variables (but instead, the whole declaration is hoisted, not just the name). Thus, the function is declared before any execution happens, and when the code is run, foo is called as it's already declared.

函数声明(和仅声明)像变量一样挂起(相反,整个声明被挂起,而不仅仅是名称)。因此,函数在执行之前被声明,当代码运行时,将调用foo,因为它已经声明。

#2


1  

From MDN:

中数:

Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.

因为在执行任何代码之前都要处理变量声明(和一般的声明),所以在代码中的任何地方声明变量就等同于在顶部声明变量。这也意味着一个变量可以在声明之前被使用。这种行为称为“提升”,因为似乎将变量声明移动到函数或全局代码的顶部。

What this means is that your function's declaration of a new t variable is effectively performed at the opening of the function. This immediately obscures the "global" t variable with the local one. However, the line of code which sets a value to that new t variable doesn't execute until after you log to the console. So the default value is undefined.

这意味着函数的新t变量声明在函数开始时被有效地执行。这立即模糊了“全局变量”与本地变量的关系。然而,为新t变量设置值的代码行直到您登录到控制台之后才执行。所以默认值没有定义。

Perhaps not the most intuitive feature of JavaScript in this example, I'll admit. But at the same time it highlights the importance of clarity in your code. Having two variables of the same name even attempt to be accessible in the same scope is a potential source for bugs. It would be better to give them different names.

我承认,在这个示例中,JavaScript可能不是最直观的特性。但与此同时,它强调了代码中清晰性的重要性。拥有两个相同名称的变量甚至尝试在相同的范围内访问都是bug的潜在来源。最好给他们起不同的名字。

#3


0  

t is both global and local.

t既是全局的,也是局部的。

When you are inside a function there is something called scope. This means you can declare variables with the same names as global ones and they will actually be completely different. Now notice where you place console.log(). If you did not decalre a variable t inside your function you would log 20 however you did so the function is concerned with the function's t. But you are logging before the t was declared!

当你在一个函数中,有一个叫做作用域的东西。这意味着您可以声明与全局变量名称相同的变量,它们实际上是完全不同的。现在请注意console.log()的位置。如果你没有在你的函数中去除一个变量t,你将会记录20,不管你怎么做,所以这个函数与函数的t有关。

var t = 20;
function test () {    
    console.log(t);
}
test();

var t = 20;
function test () {
    console.log(t);
    var t = 100;
}
test();

Your code is equivalent to: (the var is moved to the top without being defined. Something called hoisting.)

您的代码相当于:(var被移动到顶部而没有定义。所谓的提升)。

var t = 20;
function test () {
    var t;
    t = 100;
     console.log(t);
}
test();