正在加载...

作用域

你已经会声明变量、编写函数并返回值。还有一条规则决定名字是否可及:作用域。它回答:「从这里起,我能用哪些名字?」

作用域是什么意思

作用域是程序中某个名字存在的区域。在区域外,同样的写法可能看不见——或指向另一个绑定。可以想成房间:贴在厨房墙上的标签在厨房里很清楚,不会自动出现在街上。

三种日常类型

📊 全局、函数与块级作用域

类型 名字住在哪里 常用工具 哪里可见?
全局 所有函数之外 顶层的 let / const / var 整份脚本(同一页)
函数(局部) 函数体内部 参数与局部变量 仅在该函数内
块级 在 { } 内,如 if 或循环 let 与 const 仅在该块内

这三种覆盖了大部分初学者代码。函数局部保持私有。let/const 的块级绑定留在花括号里。全局是共享的——适合共用计数器,若每个名字都变全局则危险。

一个全局名

javascript
let city = "Tehran";
function showCity() {
console.log(city);
}
showCity();
console.log(city);

全局名写在函数外面

city 在顶层声明,因此函数和后面的 console.log 都能读到。改一次字符串,每个读取者都看到新值。只有多处真正共享同一值时才用全局。

函数内的局部名

javascript
function greet() {
let message = "Hello";
console.log(message);
}
greet();
// console.log(message); // Error: message is not defined

局部留在函数里

message 只在 greet 运行期间存在。在函数外,该名字未定义。参数同样:属于列出它们的那个函数。

用 let 的块级作用域

javascript
if (true) {
let score = 10;
console.log(score);
}
// console.log(score); // Error: score is not defined

let 与 const 尊重块

在 { } 内,let 或 const 绑定只在该块中可见。闭合括号之后,score 就没了。旧的 var 是函数作用域,可能从块里「漏」出去。优先用 let/const,让块边界与所见一致。

嵌套代码向外读取

javascript
let title = "Shop";
function show() {
let label = "open";
console.log(title + " is " + label);
}
show();

嵌套会向外看

show 既能读外层的 title,也能读自己的 label。查找向外走,直到找到匹配。不会向内:外层代码看不见只在函数内诞生的名字。

内层名遮蔽外层

javascript
let status = "ok";
function check() {
let status = "busy";
console.log(status);
}
check();
console.log(status);

遮蔽:函数内内层胜出

在 check 里,局部 status 盖住外层。调用打印 busy。函数结束后,外层仍是 ok。同一写法,两个绑定——作用域决定你碰到哪一个。

把带作用域的值写到页面

保留一个全局标签,在函数里拼出仍能读到它的一行,再把结果写进段落。

带作用域的页面演示

html
<!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)——外层调用结束后仍记住外层名字的函数。

练习步骤

  1. 声明全局 let app = "demo",从小函数内外各 log 一次。
  2. 在函数内放 let secret = 1;确认在外 log secret 会报错。
  3. 在 if (true) { } 内声明 let n = 5 并 log;块后再试。
  4. 从嵌套函数读取外层 let,不要重新声明。
  5. 用内层 let tag = "B" 遮蔽外层 let tag = "A",两处都 log。
  6. 在 HTML 演示中只改 place 字符串,刷新,读段落。

常见踩坑

  • 在函数外使用局部名——是 ReferenceError,不是静默空白
  • 指望块里的 var 像 let 一样保持私有
  • 以为外层代码能看见只在嵌套函数里创建的名字
  • 把作用域和 return 混为一谈——一个是可见性,一个是送出值
  • 指望在这里讲完整闭包——那是下一页

小结

  • 作用域是名字可见并可用的地方
  • 全局在函数外,整份脚本共享
  • 局部与参数留在各自函数内
  • { } 里的 let/const 是块级;优于会泄漏的 var
  • 嵌套可向外读;外层看不见仅内层的名字
  • 同名内层绑定遮蔽外层
  • 页面更新可用返回字符串组合全局与局部
  • 下一课:闭包——会记住外层名字的函数

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
8
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部