作用域
你已经会声明变量、编写函数并返回值。还有一条规则决定名字是否可及:作用域。它回答:「从这里起,我能用哪些名字?」
作用域是什么意思
作用域是程序中某个名字存在的区域。在区域外,同样的写法可能看不见——或指向另一个绑定。可以想成房间:贴在厨房墙上的标签在厨房里很清楚,不会自动出现在街上。
三种日常类型
📊 全局、函数与块级作用域
| 类型 | 名字住在哪里 | 常用工具 | 哪里可见? |
|---|---|---|---|
| 全局 | 所有函数之外 | 顶层的 let / const / var |
整份脚本(同一页) |
| 函数(局部) | 函数体内部 | 参数与局部变量 | 仅在该函数内 |
| 块级 | 在 { } 内,如 if 或循环 |
let 与 const |
仅在该块内 |
这三种覆盖了大部分初学者代码。函数局部保持私有。let/const 的块级绑定留在花括号里。全局是共享的——适合共用计数器,若每个名字都变全局则危险。
let city = "Tehran";
function showCity() {
console.log(city);
}
showCity();
console.log(city);
全局名写在函数外面
city 在顶层声明,因此函数和后面的 console.log 都能读到。改一次字符串,每个读取者都看到新值。只有多处真正共享同一值时才用全局。
function greet() {
let message = "Hello";
console.log(message);
}
greet();
// console.log(message); // Error: message is not defined
局部留在函数里
message 只在 greet 运行期间存在。在函数外,该名字未定义。参数同样:属于列出它们的那个函数。
if (true) {
let score = 10;
console.log(score);
}
// console.log(score); // Error: score is not defined
let 与 const 尊重块
在 { } 内,let 或 const 绑定只在该块中可见。闭合括号之后,score 就没了。旧的 var 是函数作用域,可能从块里「漏」出去。优先用 let/const,让块边界与所见一致。
let title = "Shop";
function show() {
let label = "open";
console.log(title + " is " + label);
}
show();
嵌套会向外看
show 既能读外层的 title,也能读自己的 label。查找向外走,直到找到匹配。不会向内:外层代码看不见只在函数内诞生的名字。
let status = "ok";
function check() {
let status = "busy";
console.log(status);
}
check();
console.log(status);
遮蔽:函数内内层胜出
在 check 里,局部 status 盖住外层。调用打印 busy。函数结束后,外层仍是 ok。同一写法,两个绑定——作用域决定你碰到哪一个。
把带作用域的值写到页面
保留一个全局标签,在函数里拼出仍能读到它的一行,再把结果写进段落。
<!DOCTYPE html>
<html>
<head>
<title>scope — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
let place = "Garden";
function line() {
let state = "open";
return place + " is " + state;
}
let box = document.getElementById("msg");
box.textContent = line();
</script>
</body>
</html>
段落显示 Garden is open。place 是全局;state 是 line 的局部。函数读两者,返回一个字符串,页面显示它。只改 place,刷新,看新行。下一课:闭包(closures)——外层调用结束后仍记住外层名字的函数。
练习步骤
- 声明全局
let app = "demo",从小函数内外各 log 一次。 - 在函数内放
let secret = 1;确认在外 logsecret会报错。 - 在
if (true) { }内声明let n = 5并 log;块后再试。 - 从嵌套函数读取外层
let,不要重新声明。 - 用内层
let tag = "B"遮蔽外层let tag = "A",两处都 log。 - 在 HTML 演示中只改
place字符串,刷新,读段落。
常见踩坑
- 在函数外使用局部名——是 ReferenceError,不是静默空白
- 指望块里的
var像let一样保持私有 - 以为外层代码能看见只在嵌套函数里创建的名字
- 把作用域和
return混为一谈——一个是可见性,一个是送出值 - 指望在这里讲完整闭包——那是下一页
小结
- 作用域是名字可见并可用的地方
- 全局在函数外,整份脚本共享
- 局部与参数留在各自函数内
{ }里的let/const是块级;优于会泄漏的var- 嵌套可向外读;外层看不见仅内层的名字
- 同名内层绑定遮蔽外层
- 页面更新可用返回字符串组合全局与局部
- 下一课:闭包——会记住外层名字的函数
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部