JavaScript-变量作用域
在 JavaScript 中定义变量有两种方式
ES6 之前: var 变量名称;
ES6 开始: let 变量名称;
两种定义变量方式的区别
是否能够定义同名变量
通过 var 定义变量, 可以重复定义同名的变量, 并且后定义的会覆盖先定义的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
var num = 123;
var num = 456;
console.log(num);
</script>
</head>
<body>
</body>
</html>
如果通过 let 定义变量,"相同作用域内"
不可以重复定义同名的变量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
let num = 123;
// 报错 Uncaught SyntaxError: Identifier 'num' has already been declared
let num = 456;
</script>
</head>
<body>
</body>
</html>
是否能够先使用后定义
通过 var 定义变量, 可以先使用后定义 (预解析)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
console.log(num);
var num = 123;
</script>
</head>
<body>
</body>
</html>
通过 let 定义变量, 不可以先使用再定义 (不会预解析)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
// 报错 Uncaught ReferenceError: Cannot access 'num' before initialization at index.html?_ijt=37c9th389lfunccvo6ijq9ebdd:8
console.log(num);
let num = 123;
</script>
</head>
<body>
</body>
</html>
是否能被 {} 限制作用域
无论是 var 还是 let 定义在 {}
外面都是全局变量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
var num = 123;
let num = 123;
</script>
</head>
<body>
</body>
</html>
将 var 定义的变量放到一个单独的 {}
里面, 还是一个全局变量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
{
var num = 123;
}
// 不会报错
console.log(num);
</script>
</head>
<body>
</body>
</html>
将 let 定义的变量放到一个单独的 {}
里面, 是一个 局部变量
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
{
let num = 123;
}
// 会报错 Uncaught ReferenceError: num is not defined
console.log(num);
</script>
</head>
<body>
</body>
</html>
在 JavaScript 中 {}
外面的作用域, 我们称之为全局作用域。
在 JavaScript 中函数后面 {} 中的的作用域, 我们称之为 "局部作用域"。
在 ES6 中只要 {}
没有和函数结合在一起, 那么应该称之为 "块级作用域"。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
{
// 块级作用域
}
if (false) {
// 块级作用域
}
while (false) {
// 块级作用域
}
for (; ;) {
// 块级作用域
}
do {
// 块级作用域
} while (false);
switch () {
// 块级作用域
}
function say() {
// 局部作用域
}
</script>
</head>
<body>
</body>
</html>
块级作用域和局部作用域的区别
在块级作用域中通过 var 定义的变量是 全局变量
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
{
// 块级作用域 ↓ 全局变量
var num = 123;
}
console.log(num);
</script>
</head>
<body>
</body>
</html>
在局部作用域中通过 var 定义的变量是 局部变量
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
function test() {
// 局部变量
var value = 666;
}
test();
console.log(value);
</script>
</head>
<body>
</body>
</html>
无论是在块级作用域还是在局部作用域, 省略变量前面的 let 或者 var 就会变成一个 全局变量
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script type="text/javascript">
function test() {
// 全局变量
value = 666;
}
test();
console.log(value);
</script>
</head>
<body>
</body>
</html>