JavaScript构造函数调用陷阱:无new调用与返回值覆盖机制详解
本文深入探讨JavaScript中构造函数调用的常见陷阱。重点分析忘记使用new关键字时this指向全局对象导致的意外副作用,以及构造函数显式返回不同类型值(基础类型与对象)对最终返回结果的影响。同时介绍了严格模式下this绑定的差异,帮助开发者避免隐蔽Bug。
前言与构造函数定义
前言
近期阅读《你不知道的JavaScript》时,注意到书中提到构造函数在调用时会绑定this。为了验证并深入理解这一机制,我在控制台进行了代码测试与详细分析。
从定义上看,构造函数是专门设计用于通过new关键字进行调用的函数。
例如:
function A(b) {
this.b = b || 'bbb';
}
随后,可以通过new关键字构建A类的实例:
var a = new A('B')
省略new调用的陷阱
然而,这里存在一个首要陷阱:构造函数在语法上与普通函数完全一致。如果故意省略new,或者不小心忘记使用new,都会导致令人困惑的错误结果:
var aa = A('adadada');
这种调用方式不会抛出显式错误,但会埋下严重隐患:
- 变量aa并非A的实例,其值变为undefined
- 全局作用域中意外多出一个名为b的变量,其值为‘adadada'
这就是省略new调用构造函数所引发的典型问题。
接下来探讨其他相关机制:
构造函数显式返回值的影响
构造函数内部包含显式返回值的情况
例如:
function A(b) {
this.b = b || 'bbb';
return {b: '0000'};
}
在此情况下,无论是否使用new调用函数A,返回结果一致,均获得一个普通对象:{b:'0000′}
值得注意的是,此时是否带new调用仍存在差异:即使不带new,函数内部依然会意外声明一个名为b的全局变量。
既然构造函数拥有显式返回值时,该返回值会取代默认的this成为最终返回结果,那么是否所有类型的返回值都能覆盖this呢?
测试显式返回值的行为
众所周知,所有函数都有返回值;若未显式指定return,则默认返回undefined。
那么,如果在构造函数中显式返回undefined,会发生什么?
var a = function (){this.b = 'b'; return undefined};
new a(); // {b:'b'}
显式返回undefined并不能阻止构造函数调用时的默认行为。
下图展示了更多测试用例:

简要总结如下:
当显式返回undefined、null、boolean、number等基础类型时,不会取代new调用的默认行为。
但若显式返回{}、[]、RegExp、Date、Function等对象类型,则会取代new调用的默认返回值this。
观察可见,上述第二类返回值均为对象,属于复杂类型。
严格模式与全局对象绑定
补充记录
前文提及,本应通过new调用的构造函数若被当作普通函数调用,且函数体内包含 this.x = xxx 这类赋值语句,该属性将被赋值给全局对象(即window),从而成为全局变量。
其原因众所周知,书中也专门阐述:普通函数调用时,默认的this绑定至全局对象。
书中还指出:若函数体处于严格模式,则不会将this绑定至全局对象,例如:
var a = function (){'use strict';this.b = 'b'; return /111/g};
a(); // 直接报错
因为在严格模式下,默认的this指向undefined
因此,有两点需要特别强调:
- 严格模式的优势
- 若计划声明构造函数,启用严格模式是非常必要的
总结
以上就是本文的全部内容,希望这些内容能对大家的JavaScript学习或工作有所帮助。如有任何疑问,欢迎留言交流。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
