JavaScript构造函数调用陷阱:无new调用与返回值覆盖机制详解

作者:异步漫步

时间:2026-10-21

浏览:625

本文深入探讨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');

这种调用方式不会抛出显式错误,但会埋下严重隐患:

  1. 变量aa并非A的实例,其值变为undefined
  2. 全局作用域中意外多出一个名为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

因此,有两点需要特别强调:

  1. 严格模式的优势
  2. 若计划声明构造函数,启用严格模式是非常必要的

总结

以上就是本文的全部内容,希望这些内容能对大家的JavaScript学习或工作有所帮助。如有任何疑问,欢迎留言交流。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章