我正在学习使用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
答案 0 :(得分:2)
这完全按照预期的方式运行:悬挂了“年龄”和“职业”的声明(but not assigned values),因此您的控制台日志显示它们的存在值为“未定义”(而不是抛出{ {1}}),但ReferenceError
是特殊的:您不是声明它的人,即使您的代码使它看起来像 一样:
真正发生的是,您编写的代码是作用域内的,因此,当您说name
时,您实际编写的是var name = "tom"
。在任何类型的显式作用域(函数,模块等)中,此行为都将达到您期望的方式,但在浏览器的 global 范围中(或更确切地说,“在您的作用域为currentscope.name = "tom"
”),这意味着您的代码实际上以window
的身份执行。
这就是问题所在:window.name = "tom"
already exists as a global property on the window
object
当然,这也适用于其他任何值,如果您在全局范围内使用name
,则与var numbats = "cute";
相同,因此,如果您不想遇到无声的命名冲突:请不要在全局范围内声明事物。在一个函数中进行测试(其中window.numbats = "cute";
将shadow全局var name
),或者您可以使用现代JS并使用name
代替大括号,但是当然可以我们不再使用let
。
一个鲜为人知的事实:将全局var
设置为name
,然后在同一标签中浏览网络一小时,即使是一小时后,"tom"
仍然是您的价值,除非别人改变了它,这几乎永远不会发生。这是保持多方位跟踪的一种有趣的方式。