前端进阶之旅前端进阶之旅
  • 基础篇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 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库构造函数 return 对象或原始值时 new 的结果
JSJavaScript对象与原型

当一个构造函数显式返回一个对象时,new 表达式的结果是什么?如果返回原始值呢?

当构造函数显式返回一个对象时,new 表达式的结果是该对象;若返回原始值(如 number、string、boolean、null、undefined),则忽略返回值,改用新创建的 this 对象。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#对象与原型
先看核心答案读代码示例
理解线索

构造函数返回值与 new 的协议

  1. 默认行为无返回或返回原始值时,new 得 this
  2. 对象覆盖返回非 null 对象则替换默认实例
  3. 原始值范围undefined、null、数字、字符串、布尔

关键是返回值类型:对象与原始值的处理完全不同,null 按原始值对待。

核心回答

先记住这个答案

执行 new 时,先创建一个新对象并链接原型,然后以它为 this 调用构造函数。若构造函数返回一个对象(非 null 的函数、数组、正则、对象字面量等),则 new 的最终结果是这个返回对象,this 对象被丢弃。若返回原始值或没有 return,则 new 结果仍是新建的 this 对象。null 是原始值,因此也被忽略。

  • 返回对象则覆盖 new 创建的实例
  • 返回原始值(含 null)则被忽略
  • class 构造器也能返回对象覆盖 this

new 执行流程中的返回值判定

new 操作符内部先创建一个普通对象,将该对象的 [[Prototype]] 指向构造函数的 prototype 属性(若 prototype 是对象)。然后以该新对象为 this 调用构造函数。执行完毕后,JavaScript 检查构造函数的返回值类型:若返回一个对象(typeof 为 'object' 且不为 null,或 typeof 为 'function'),则整个 new 表达式的结果就是这个返回值;若返回原始类型(number、string、boolean、null、undefined、symbol、bigint),则丢弃返回值,返回之前创建的 this 对象。

这个规则适用于普通函数和 ES6 class 的 constructor。class 构造器若显式返回对象,也会覆盖 this,虽然 class 必须用 new 调用。值得注意的是,返回一个函数或数组也属于对象,因此同样会覆盖。若返回 null,因为 typeof null 是 'object' 但规范明确将 null 视为原始值,所以 new 的结果仍是 this。

演示返回值对 new 结果的影响JavaScript
function MakeObject(flag) {
  this.name = 'this对象';
  if (flag) {
    return { name: '返回对象' };
  }
  return '原始值';
}
const a = new MakeObject(true);
const b = new MakeObject(false);
console.log(a.name); // 返回对象
console.log(b.name); // this对象

class C {
  constructor() {
    this.x = 1;
    return { y: 2 }; // 覆盖 this
  }
}
const c = new C();
console.log(c.x); // undefined
console.log(c.y); // 2
查看输出与解释
返回对象
this对象
undefined
2

MakeObject 返回对象时 new 得到该对象;返回字符串时 new 得到 this。class 构造器返回对象同样覆盖 this,导致 this.x 不存在。

单例模式:用返回对象强制复用实例

假设我们需要一个配置管理器,整个应用只允许一个实例。可以用构造函数返回已有的实例:在函数内部用一个私有变量保存实例,每次调用构造时若已存在则返回该实例,否则创建新对象并赋值给私有变量。这样即使有人多次使用 new ConfigManager(),得到的也是同一个对象,因为构造函数显式返回了那个已存在的对象。

这种模式要求构造函数能区分是否已有实例,但注意它改变了 new 的常规语义:每次 new 产生的并不是新建的对象。缺点是一旦有人修改了返回对象上的属性,会影响所有引用者。更好的做法是用 Symbol 或静态属性保存实例,但这里的关键是利用“返回对象即覆盖”的特性。处理时还需防范实例为 undefined 或 null 的情况,因为 null 会被忽略。

利用返回对象实现单例JavaScript
let instance = null;
function ConfigManager(options) {
  if (instance !== null) {
    return instance;
  }
  instance = this;
  this.options = options;
}
const c1 = new ConfigManager({ debug: true });
const c2 = new ConfigManager({ debug: false });
console.log(c1 === c2); // true
console.log(c1.options.debug); // true
console.log(c2.options.debug); // true
查看输出与解释
true
true
true

第二次 new 时 instance 已存在,构造函数返回 instance,使 c2 与 c1 相同。该代码可在浏览器或 Node 中运行,无副作用。

边界:返回的对象不能是 null 或原始值的包装对象?

一个常见误区是认为返回包装对象如 new Number(3) 也能覆盖,其实可以,因为包装对象是对象。但返回 null 时 typeof 是 'object',却仍按原始值处理,所以 new 结果仍是 this。另一个边界是如果构造函数的 prototype 属性不是对象(例如被改为基本类型),new 创建的新对象的原型会变为 Object.prototype,但返回值规则不变。

对 class 而言,class 构造器不能返回原始值,但可以返回对象,这同样会覆盖 this。此外,若构造函数返回的对象与 this 无关,则后续指向 this 的操作(如给 this 添加属性)都不会生效,因为 this 已被丢弃。实际判断时建议用 typeof 检查返回值,但必须排除 null;更精确的是用 Object(value) === value 判断是否为对象。

回答前,多想一步

容易答错的地方

认为返回 null 会被当成对象覆盖
虽然 typeof null 是 'object',但 ECMAScript 规范明确将 null 归为原始值,因此构造函数 return null 时,new 仍返回新建的 this,而不是 null。判断时应使用严格对象检查:value !== null && (typeof value === 'object' || typeof value === 'function')。
以为 class 构造器不能返回对象
ES6 class 的构造器在 new 时同样遵循返回值规则:若返回对象,则 new 的结果是该对象,this 会被丢弃。许多开发者误以为 class 构造器必须返回 undefined 或 this,实际上返回对象是合法的,只是很少使用。示例:class A { constructor() { return {}; } } 得到空对象。
试着用自己的话回答

面试官还会怎么问?

箭头函数可以用作构造函数吗?

不能,箭头函数没有 [[Construct]] 内部方法,使用 new 会抛出 TypeError。同样,对象方法简写(method() {})也不可构造,因为其没有 constructor 行为。只有普通函数和 class 才具备构造能力。

new.target 与返回值判断有什么关系?

new.target 可以检测函数是否被 new 调用,但它与返回值无关。即使构造函数返回对象,new.target 仍指向该构造函数。若要避免误用 new,可结合 new.target 和返回值规则设计更安全的工厂函数。

如果返回一个函数,new 的结果是什么?

因为函数也是对象,返回函数时 new 表达式的结果就是该函数对象,而不是 this。例如 function F() { return function(){}; },new F() 得到一个函数,且该函数的 prototype 不会自动设置。

从一道题,走向一组知识

把知识连起来

对象与原型

在 ES6 class 的构造器中必须先调用 super() 吗?为什么?

同属「对象与原型」专题,接着看 class 构造器 super this 绑定顺序 在具体场景中的处理方式。

对象与原型

在严格模式下修改 writable:false 的属性会怎样?非严格模式呢?

同属「对象与原型」专题,接着看 writable false 严格模式与非严格模式赋值结果 在具体场景中的处理方式。

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

参考资料

  • new

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

本题目录
  1. 先记住这个答案
  2. new 执行流程中的返回值判定
  3. 单例模式:用返回对象强制复用实例
  4. 边界:返回的对象不能是 null 或原始值的包装对象?
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

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

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