javascript严格模式是什么_它如何改变代码的执行方式?

严格模式下会直接报错的语法包括:with语句被禁用;arguments.callee/caller访问抛TypeError;给只读属性赋值、eval中声明变量、删除未声明变量、对象字面量重复属性名均报错。

严格模式下哪些语法会直接报错?

启用严格模式后,JavaScript 会拒绝一些原本“宽容”的语法,让错误提前暴露。比如:with 语句完全禁用,arguments.calleearguments.caller 访问抛出 TypeError,给只读属性赋值(如 NaN = 1)或在 eval 中声明变量也会立即失败。

常见踩坑点:

  • function f() { "use strict"; var x; x = 1; } —— 这样没问题;但若漏写 var/let/constx = 1 会直接报 ReferenceError
  • delete x(删除未声明变量)在非严格模式返回 true,严格模式下抛 SyntaxError
  • 对象字面量中重复属性名(如 {a: 1, a: 2})在严格模式下是语法错误

"use strict" 的作用域和启用方式有哪些限制?

严格模式不是全局开关,它只对当前作用域生效。最常用的是函数级启用:

"use strict";
function foo() {
  // 这里是严格模式
}
function bar() {
  "use strict";
  // 这里也是严格模式
}

注意:

  • 不能在 iftry 块内写 "use strict" —— 它必须是脚本或函数体的**首条可执行语句**(前面只能有注释)
  • 模块(.mjstype="module" 的 script)默认启用严格模式,无需手动加 "use strict"
  • 箭头函数不支持单独启用严格模式,它继承外层函数的严格状态

严格模式如何影响 this 和变量绑定?

这是最常被忽略的实际影响点。非严格模式下,顶层函数中的 this 指向 window(浏览器)或 global(Node.js);严格模式下,它为 undefined

function foo() {
  "use strict";
  console.log(this); // undefined
}
foo();

变量绑定也更严格:

  • eval 不再能向外部作用域注入变量(eval("var x = 1") 不会让 x 出现在外层)
  • 函数参数名不允许重复(function f(a, a) {} 在严格模式下是语法错误)
  • arguments 不再与形参自动同步(function f(a) { "use strict"; a = 2; console.log(arguments[0]); } 输出仍是原值,而非 2

严格模式对性能和调试有什么实际帮助?

现代引擎(V8、SpiderMonkey)在严格模式下可以做更多优化:比如禁止 with 让作用域链更可预测,禁用 arguments.callee 避免隐藏的函数引用开销。更重要的是调试体验:

  • 静默失败变显式报错(如给 undefined 添加属性不再忽略)
  • Chrome DevTools 在严格模式下调用栈更干净,不会混入 eval 注入的上下文
  • ESLint 等工具默认按严格模式校验,不加 "use strict" 可能导致某些规则误报

真正麻烦的不是“要不要用”,而是混合使用:一个文件部分函数启用了严格模式,另一些没启,this 行为不一致、错误定位成本陡增。所以建议全项目统一,要么全部模块化(天然严格),要么每个函数/脚本顶部明确声明。