严格模式
有几处错误以前会悄悄过去。严格模式把它们拦住。"use strict" 要写在最前面。此后,size = "regular" 既没有 let 也没有 const,就不会造出全局名字,而是抛出 ReferenceError。这一页上的那一行就是 ReferenceError。
待办和错误页是另外的结局
待办停在 done: buy tea。错误页故意抛了 new Error("missing size"),catch 读的是那句消息。这一页不抛你自己写的 Error。引擎抛出,是因为 size 从未声明。console.error 仍然不会抛。
指令只有一个位置有效
"use strict" 只有作为脚本的第一条语句,或者作为某一个函数里的第一条语句,才会生效。后面再出现的字符串什么都不会改变。可以只有一个函数是严格的,脚本其余部分不是。模块本来就是严格的,所以那里的指令是多余的。
setSize 在做什么
setSize 给 size 赋值,却没有声明它。调用放在 try 里。不会出现全局的 size。
"use strict";
function setSize() {
size = "regular";
}
try {
setSize();
} catch (error) {
console.log(error.name);
}
日志是 ReferenceError。修法是 let size = "regular"。若 drink 是 tea,并且 size 已经这样声明,label 可以返回 tea / regular。写成 order.size 是另一种说得通的改法,因为那个名字确实存在。
用名字调用,和在对象上调用
按函数自己的名字调用,不会设置 this。严格模式里 this 是 undefined。在 order 上调用方法,会把 this 设成那个对象,于是 this.drink 是 tea。
"use strict";
function bare() {
return this;
}
const order = {
drink: "tea",
label() {
return this.drink;
}
};
console.log(bare());
console.log(order.label());
两次日志先是 undefined,然后是 tea。不要在 bare 里面读 this.drink。那里没有对象,这样读会抛出。
四处不同
左边是从前那种静默行为。右边是这条指令做成的结果。
📊 这条指令改了什么
| 旧的静默行为 | 使用 "use strict" |
|---|---|
| 未声明就写 size = "regular" 会创建全局名字 | ReferenceError |
| bare 里的 this 是全局对象 | undefined |
| 重复参数时后一个生效 | SyntaxError |
| 对已声明变量使用 delete 会返回 false | SyntaxError |
重复的参数,或者 delete size,在脚本被读取时就失败,那是 SyntaxError,try 抓不到。赋值带来的 ReferenceError 发生在函数运行时,所以 catch 看得到。只要属性可以删掉,delete order.drink 在两种模式里都仍然允许。
这个页面
页面是一段严格脚本。赋值失败,错误的名字被写到页面上。
<!DOCTYPE html>
<html>
<body>
<p id="line">…</p>
<script>
"use strict";
const line = document.querySelector("#line");
try {
size = "regular";
} catch (error) {
line.textContent = error.name;
}
</script>
</body>
</html>
这一行读作 ReferenceError。不是 done: buy tea。也不是 caught / missing size。在 size 前面加上 let,这个 catch 就不再运行。
五个短练习
- 在 "use strict" 下运行 setSize。日志是 ReferenceError。
- 把赋值改成 let size = "regular"。抛出消失。
- 调用 bare()。值是 undefined。
- 调用 order.label()。值是 tea。
- 读页面。这一行是 ReferenceError。
真会踩到的地方
- 把指令放在另一条语句后面
- 以为未声明的赋值会造出全局名字
- 在 bare 调用里读 this.drink
- 用 try 去接重复参数
- 把这一行读成 done: buy tea
- 把这一行读成 caught / missing size
记住这些
- 指令放在最前
- 未声明的 size = "regular" 抛出 ReferenceError
- bare 里的 this 是 undefined,order.label() 返回 tea
- 重复参数和对变量使用 delete 都是 SyntaxError
- 页面上的那一行是 ReferenceError
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部