“new” 的不一致使用¶
ID: js/inconsistent-use-of-new
Kind: problem
Security severity:
Severity: warning
Precision: very-high
Tags:
- reliability
- correctness
- language-features
Query suites:
- javascript-security-and-quality.qls
JavaScript 不强制区分构造函数和普通函数,因此同一个函数可以用 new
作为构造函数调用,也可以不带 new
作为普通函数调用。但是,这很不寻常,通常表明存在错误。
建议¶
检查相关函数及其所有调用。如果它实际上不打算作为构造函数调用,则将其所有构造函数调用改为普通函数调用。如果它确实打算作为构造函数调用,则要么将其所有普通函数调用改为构造函数调用,要么引入一个保护机制来拦截不带 new
的调用,如下所述。
示例¶
在以下示例中,Point
明显打算是一个构造函数,但在第 7 行,它是在不带 new
的情况下调用的。这意味着函数体中的 this
将引用全局对象,因此对 x
和 y
的赋值将创建全局变量。
function Point(x, y) {
this.x = x;
this.y = y;
}
var p = new Point(23, 42),
q = Point(56, 72);
解决此问题的最简单方法是将第 7 行的调用改写为使用 new
function Point(x, y) {
this.x = x;
this.y = y;
}
var p = new Point(23, 42),
q = new Point(56, 72);
或者,如果你必须能够在带和不带 new
的情况下调用 Point
,你可以插入一个保护机制来拦截不带 new
的调用,如下所示
function Point(x, y) {
if (!(this instanceof Point))
return new Point(x, y);
this.x = x;
this.y = y;
}
var p = new Point(23, 42),
q = Point(56, 72);
现在,如果 Point
在不带 new
的情况下调用,它的 this
对象(即全局对象)就不是 Point
的实例,因此将执行 if
语句的“then”分支,它将使用相同参数再次调用 Point
,但这次带 new
。
参考资料¶
D. Crockford,《JavaScript:好用的部分》,附录 B.11。O’Reilly,2008 年。