前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库new 调用函数内部步骤 this 绑定
JSJavaScript函数与作用域

使用 new 调用函数时,函数内部会发生哪些步骤?this 如何绑定?

用 new 调用函数时,引擎会先创建新对象并链接其原型,再以该对象为 this 执行函数体,最后根据返回值决定整个表达式的结果。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#函数与作用域
先看核心答案
理解线索

`new` 调用机制

  1. 创建空对象新对象无自有属性
  2. 原型链关联实例继承构造器 prototype
  3. this 指向函数内部 this 为新建对象

若构造函数显式返回非原始值,实例会被替换;返回原始值则忽略。

核心回答

先记住这个答案

当函数被 new 调用时,会经历四步:创建空对象;将该对象的 [[Prototype]] 指向构造函数的 prototype 属性;以该对象作为 this 执行函数体;若函数返回对象则返回该对象,否则返回之前创建的对象。this 在步骤中被固定为新对象,因此构造函数内可直接给 this 添加属性。

  • new 会创建新对象作为 this
  • 原型关联到构造函数的 prototype
  • 构造函数返回对象会覆盖实例

四步流程的完整推导

第一步,创建空白对象。此对象是普通对象,其内部 [[Prototype]] 暂未设置。第二步,将该对象的 [[Prototype]] 指向构造函数当前的 prototype 属性。注意如果构造函数的 prototype 不是对象,则新对象保持继承 Object.prototype,这对内置类型如 Number 的构造不常用。

第三步,以该新对象为 this 调用函数,函数体内所有 this 赋值都会写入此对象。第四步,根据返回值分流:若函数返回对象或函数,则整个 new 表达式结果就是该返回值;否则返回首次创建的对象。这解释了为何构造函数极少写返回语句,但若刻意返回对象可覆盖默认实例。

统一实例工厂的构造实现

场景:需要设计一个可配置的日志器构造工厂,允许外部传入多种存储适配器。通过 new Logger(type) 创建实例时,内部根据 type 决定使用内存或本地存储。为了兼容直接调用,代码用 new.target 检测:若未用 new,则自动递归 new 自身,确保 this 绑定正确。

实现时,构造器内 if (!new.target) return new Logger(type),并基于 type 给 this.store 赋值方法。这种设计让调用者不必区分调用形式。关键点在于显示返回对象不会造成问题,因为整个表达式始终返回实际实例,但注意避免在递归时重复检测造成死循环。

失效条件与处理代价

边界一:当构造函数的 prototype 被重新赋值为原始类型时,新对象的原型会退化为 Object.prototype,导致原有方法无法访问。这常见于代码动态修改 prototype 后未及时还原,出现实例丢失原型方法的现象,且难以察觉。

处理方案:在构造函数内部用 Object.setPrototypeOf 强制修正或检测原型类型。但代价是每次构造都要额外代码,且影响性能。更稳妥的是,保持构造函数 prototype 始终为对象,避免重新赋值为非对象。若必须动态修改,建议使用 Object.create 替代 new 模式。

回答前,多想一步

容易答错的地方

认为构造函数不能返回对象
很多人以为构造器内写 return 没意义,实际上显式返回对象会替换默认实例。例如返回 { custom: true } 时,即使用 new,结果也不是 this 生成的对象。这是合法覆盖机制,不是错误。
忽略 `new.target` 区分调用方式
普通函数调用与 new 调用时 this 完全不同,但不少开发者直接用 this 全局对象。用 new.target 可判断是否通过 new 调用,从而避免误污染全局。类若无 new 会直接抛错,但普通函数不会。
试着用自己的话回答

面试官还会怎么问?

箭头函数能否用 `new` 调用?为什么?

不能。箭头函数没有 [[Construct]] 内部方法,也没有 prototype 属性,所以用 new 调用会抛出 TypeError。箭头函数中的 this 来自词法环境,不受 new 影响。

`new.target` 在继承场景中如何表现?

在构造函数中,new.target 指向实际被 new 调用的函数,而非继承链上的父类。若子类构造内调用 super(),new.target 保持为子类,父类可使用它判断实例来源。

`Reflect.construct` 与 `new` 有什么区别?

Reflect.construct 允许指定新对象的原型,可模拟某些特殊继承;它不依赖函数自身的调用形式,且可通过 newTarget 参数控制 new.target 的值。但内部步骤相同,均遵循创建、原链、this、返回值。

从一道题,走向一组知识

把知识连起来

函数与作用域

箭头函数中的 this 是如何决定的?为什么会词法绑定?

同属「函数与作用域」专题,接着看 箭头函数 this 词法绑定原理 在具体场景中的处理方式。

函数与作用域

箭头函数为什么没有自己的 arguments 对象?如何获取所在外层函数的 arguments?

同属「函数与作用域」专题,接着看 箭头函数没有 arguments 获取外层 arguments 在具体场景中的处理方式。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • new

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

本题目录
  1. 先记住这个答案
  2. 四步流程的完整推导
  3. 统一实例工厂的构造实现
  4. 失效条件与处理代价
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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