变量'name'不返回未定义



我正在学习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

为什么名称不是未定义的,而其他变量是未定义的?

编辑:

我的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

这正是它应该做的:"年龄"one_answers"职业"的声明(但没有赋值(被挂起,所以控制台日志显示它们存在,值为"未定义"(而不是抛出ReferenceError(,但name很特别:你不是声明它的人,即使你的代码让它看起来像

真正发生的事情是,你写的代码是有范围的,所以当你说var name = "tom"时,你实际上写的是currentscope.name = "tom"。在任何类型的显式作用域(函数、模块等(中,这都将按照您预期的方式执行,但在浏览器中的全局作用域中(或者更准确地说,"在任何作用域为window的执行上下文中"(,这意味着您的代码实际上以window.name = "tom"的形式执行。

这就是问题所在:name已经作为window对象的全局属性存在

当然,这也适用于任何其他值,如果你在全局范围内var numbats = "cute";,这与window.numbats = "cute";相同,所以如果你不想遇到静默命名冲突:不要在全局范围中声明东西。在函数中测试这一点(其中var name将覆盖全局name(,或者您可以使用现代JS并使用let而不是花括号块,但当然我们不再使用var了。

有趣的鲜为人知的事实:将全局name设置为"tom",然后在同一个选项卡中浏览一个小时,即使一个小时后,window.name仍然是你的价值,除非其他人更改了它,这几乎从未发生过。这是一种有趣的方式,使多方面的跟踪成为可能。

最新更新