我正在学习 JavaScript 中的提升。当我尝试这段代码时
console.log('name', name)
console.log('age', age)
console.log('occupation', occupation)
var name = 'tom'
var age = '23'
var occupation = 'builder'
在我的 chrome 开发者工具中我得到了
name tom
age undefined
occupation undefined
为什么 name 不是 undefined 而其他变量是?
编辑:
我的 html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src = "index.js"></script>
</body>
</html>
我的 index.js 文件
console.log('name', name)
console.log('age', age)
console.log('occupation', occupation)
var name = 'tom'
var age = '23'
var occupation = 'builder'
我重新启动了计算机,创建了新文件,但没有任何改变。 在 Firefox 中,我得到了
name <empty string>
age undefined
occupation undefined
最佳答案
这完全按照预期的方式工作:“age”和“occupation”的声明 (but not assigned values) 被提升,因此您的控制台日志显示它们存在且值为“undefined”(而不是抛出一个 ReferenceError
),但是 name
是特殊的:您不是声明它的人,即使您的代码使它看起来像您一样:
真正发生的是你写的代码是有作用域的,所以当你说 var name = "tom"
时,你实际写的是 currentscope.name =“汤姆”
。在任何类型的显式范围(函数、模块等)中,这将按您预期的方式运行,但在浏览器的 global 范围内(或更准确地说,“在您执行的任何执行上下文中” scope 是 window
"),这意味着您的代码实际上作为 window.name = "tom"
执行。
这就是问题所在:name
already exists as a global property on the window
object
当然,这也适用于任何其他值,如果您在全局范围内 var numbats = "cute";
,则与 window.numbats = "cute";
所以如果你不想遇到无声的命名冲突:不要在全局范围内声明东西。在函数中对此进行测试(其中 var name
将 shadow 全局 name
),或者您可以使用现代 JS 并使用 let
而不是大括号 block ,但当然我们不再使用 var
。
鲜为人知的有趣事实:将全局 name
设置为 "tom"
,然后在同一个选项卡中浏览 web 一个小时,即使一个小时后,仍然将 window.name
作为您的值,除非其他人更改了它,这几乎不会发生。这是使多方位跟踪成为可能的有趣方式之一。
关于javascript - 变量 'name' 不返回未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61444189/