JavaScript函数中return与this写法的性能及内存影响分析
两种JS对象构造写法的差异与性能对比
待对比代码实现
构造函数挂载this实现(Foo)
function Foo(context) { let mode; function setMode(m) { mode = m; } function doStuff() { if(mode === 'param') { // ... 基于context执行逻辑 } else { // ... 基于context执行另一套逻辑 } } this.setMode = setMode; this.doStuff = doStuff; }
调用方式:需要通过new关键字生成实例,方法挂载在实例自身
const f = new Foo(); f.setMode('param'); f.doStuff(stuff);
工厂函数返回对象实现(Bar)
function Bar(context) { let mode; function setMode(m) { mode = m; } function doStuff() { if(mode === 'param') { // ... 基于context执行逻辑 } else { // ... 基于context执行另一套逻辑 } } return { setMode, doStuff, } }
调用方式:不需要new,直接执行函数即可拿到挂载了方法的普通对象
const b = Bar(); b.setMode('parampam'); b.doStuff(stuff); // 原示例此处笔误写为f.doStuff
核心疑问:这两种实现方式(
return返回对象 vsthis挂载实例方法)在性能、内存占用等维度是否存在优势差异?本人已了解词法this作用域与闭包的工作原理,希望明确该写法选择是仅为语法区别,还是存在实际的性能影响?
核心差异与性能、内存表现
两者并非单纯的语法区别,在底层实现、可拓展性、极端场景性能上存在明确差异,但绝大多数日常业务场景下差异可以忽略,具体对比如下:
本质逻辑差异
- Foo是标准构造函数模式:
new调用时,JS引擎会自动创建一个继承自Foo.prototype的空对象,将构造函数内的this绑定到该对象,执行完挂载逻辑后默认返回这个实例。实例可以通过instanceof Foo判断类型,也可以顺着原型链共享方法。 - Bar是工厂函数模式:不需要
new触发构造逻辑,每次执行都会手动创建一个原型指向Object.prototype的普通对象返回,和Bar函数的prototype属性没有任何关联,默认无法通过原型链共享属性或方法,也无法用instanceof判断实例和Bar的关系。
内存占用差异
- 就上述给出的两段示例代码而言,两者内存占用没有区别:每次调用函数生成实例时,都会在当前函数作用域内重新创建
setMode、doStuff两个函数,每个实例持有的闭包也会独立保存自己作用域内的mode、context变量,不存在方法共享。 - 如果做原型优化,Foo模式的内存优势会非常明显:如果把两个方法挂载到
Foo.prototype上,无论new多少个Foo实例,所有实例都会共享原型上的同一份方法,不需要每次创建实例都生成新的函数对象,实例量级越大内存优势越突出。而工厂函数模式天生不支持这种原型共享,除非手动把方法抽到函数外部做全局共享,否则每次调用都会生成新的方法副本。
运行性能差异
- 实例创建效率:现代JS引擎(V8、SpiderMonkey等)对构造函数的创建逻辑有更成熟的优化,在单次创建十万级以上实例的场景下,构造函数写法比工厂函数快10%~30%,日常少量创建实例时感知不到差异。
- 属性访问效率:构造函数生成的实例会被引擎分配固定的隐藏类(Hidden Class),属性结构在构造完成后就固定,引擎可以做更快的属性寻址优化;工厂函数返回的普通对象如果后续存在增删属性的操作,很容易脱离引擎的快属性优化路径,在百万次级别的热点属性访问场景下,速度会比构造函数实例慢20%左右,普通业务场景无感知。
- 方法调用效率:两者没有可测量的差异,闭包变量访问、方法执行的逻辑在引擎层面的优化优先级一致,日常使用不会有区别。
写法选择建议
- 如果你不需要原型继承、不需要做实例类型判断、实例创建量级很小,两种写法任选即可,和团队代码风格保持一致就行。
- 如果需要创建大量同类型实例、要实现继承逻辑、希望代码在热点路径下获得引擎更多优化,优先选构造函数模式(ES6的
class语法本质就是构造函数+原型的语法糖,性能表现一致)。 - 如果需要严格封装私有变量、想避免调用者漏写
new导致的this污染全局问题、不需要继承相关能力,工厂函数写法更省心,容错性更高。
内容的提问来源于stack exchange,提问作者mtx
相关产品推荐
相关产品推荐

