前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库严格模式函数内 this 为 undefined
JavaScript模块与语言机制

严格模式下普通函数里的 this 为什么是 undefined?

非严格模式下,普通函数直接调用时 this 会自动指向全局对象(浏览器里是 window)。严格模式取消了这个自动绑定,this 变成 undefined。好处是如果你不小心在函数里写了 this.x = 1,严格模式会立刻报错,而不是偷偷往全局对象上加属性。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#模块与语言机制
先看核心答案读代码示例
理解线索

两种模式下 `this` 的差异

  1. 非严格模式普通调用时引擎自动把 this 绑定到全局对象
  2. 严格模式不做自动绑定,this 保持 undefined
  3. 不受影响的场景有明确调用者的写法(方法调用、bind、new)不受影响

箭头函数没有自己的 this,它从外层继承,所以严格模式这条规则对箭头函数无效。

核心回答

先记住这个答案

普通函数直接调用(不是作为方法,也没有用 call 或 apply 指定接收者),在非严格模式下 this 会被自动绑定到全局对象。严格模式取消了这个自动绑定,this 就是 undefined。这样做的好处是让误操作立刻暴露:如果函数里写了 this.name = 'test',非严格模式会在全局对象上创建 name 属性,严格模式则会因为访问 undefined 的属性而抛 TypeError。

  • 非严格模式普通调用时 this 是全局对象
  • 严格模式普通调用时 this 是 undefined
  • 方法调用或 bind 绑定过的不受影响
  • ESM 普通函数直调的 this 未绑定

两种模式下 this 的对比

下面用一段代码直接看差异。

普通调用时 this 的值JavaScript
function showThis() {
  'use strict'
  return this
}

function showThisSloppy() {
  return this
}

console.log(showThis() === undefined)
console.log(typeof showThisSloppy())
查看输出与解释
true
object

showThis 开了严格模式,直接调用返回 undefined。showThisSloppy 是非严格的,返回全局对象(typeof 结果是 object)。"use strict" 写在函数体内只影响这一个函数,不影响外面。

哪些调用方式不受影响

严格模式只改变了「没有明确调用者」时 this 的默认值。下面这些写法不受影响。

obj.fn() 这样的方法调用,this 是 obj。fn.call(obj) 和 fn.apply(obj) 手动指定了 this。fn.bind(obj) 返回的新函数永远绑定 obj。new fn() 里 this 指向新创建的实例。这些场景里 this 都有明确的来源,引擎不需要做「自动绑定到全局」这个兜底操作,所以严格不严格结果一样。

用 call 传 null 的区别JavaScript
function getThis() {
  'use strict'
  return this
}

function getThisSloppy() {
  return this
}

console.log(getThis.call(null) === null)
console.log(typeof getThisSloppy.call(null))
查看输出与解释
true
object

用 call 传 null 或 undefined 时,非严格模式会把它替换成全局对象,严格模式原样保留。这也是同一条规则:非严格模式总想给 this 找一个对象,严格模式不做任何转换。

实际项目里的影响

现在写的代码大部分都是 ES 模块,ES 模块默认就是严格模式,所以函数里 this 为 undefined 是日常行为,不需要手动开启。

一个容易踩坑的场景是回调函数。把对象的方法传给 setTimeout,this 不再指向原来的对象。在非严格模式下它变成全局对象,好歹能跑通(虽然结果不对);在严格模式下它是 undefined,直接报错。这反而是好事,报错比静默出错更容易发现问题。解决方案是用箭头函数或 bind。

回答前,多想一步

容易答错的地方

以为箭头函数的 this 也会变成 undefined
箭头函数没有自己的 this,它用的是定义时外层作用域的 this。如果外层是模块顶层,那确实是 undefined;如果外层是一个方法调用,this 就是那个对象。箭头函数的 this 和严格模式这条规则无关。
以为严格模式会影响方法调用
obj.fn() 这种写法里,this 始终是 obj,不管严不严格。严格模式只改变「光秃秃调用一个函数」时的默认值,有明确调用者的情况不受影响。
试着用自己的话回答

面试官还会怎么问?

非严格模式下 this 为什么要指向全局对象?

这是 JavaScript 早期的设计。当时没有 let 和 const,全局变量和全局对象属性是一回事。函数里 this 指向全局对象让你可以用 this.setTimeout 这样的写法访问全局 API。现在看来这个设计弊大于利,所以严格模式把它去掉了。

class 里的方法是严格模式吗?

是的。class 内部整体都是严格模式,包括构造函数和所有方法。所以如果你把 class 的方法提取出来直接调用,this 就是 undefined。这也是 React 早期 class 组件需要在构造函数里 bind 方法的原因。

setTimeout 回调里的 this 是什么?

非严格模式下是全局对象,严格模式下是 undefined。setTimeout 内部相当于直接调用你传进去的函数,没有指定 this。如果需要保持 this,用箭头函数或者 bind。

从一道题,走向一组知识

把知识连起来

模块与语言机制

ES 模块顶层的 this 是什么?为什么和普通脚本不一样?

模块顶层的 this 也是 undefined,但原因不同:模块有自己的作用域,不挂在全局上。

模块与语言机制

为什么 import 声明只能写在模块顶层?

import 必须在模块顶层是模块和脚本的语法差异,和严格模式 this 变化一样都是模块独有的行为。

参考资料

  • JavaScript:模块与语言机制参考资料

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 两种模式下 this 的对比
  3. 哪些调用方式不受影响
  4. 实际项目里的影响
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑