CodeQL 文档

“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

单击查看 CodeQL 代码库中的查询

JavaScript 不强制区分构造函数和普通函数,因此同一个函数可以用 new 作为构造函数调用,也可以不带 new 作为普通函数调用。但是,这很不寻常,通常表明存在错误。

建议

检查相关函数及其所有调用。如果它实际上不打算作为构造函数调用,则将其所有构造函数调用改为普通函数调用。如果它确实打算作为构造函数调用,则要么将其所有普通函数调用改为构造函数调用,要么引入一个保护机制来拦截不带 new 的调用,如下所述。

示例

在以下示例中,Point 明显打算是一个构造函数,但在第 7 行,它是在不带 new 的情况下调用的。这意味着函数体中的 this 将引用全局对象,因此对 xy 的赋值将创建全局变量。

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 年。

  • ©GitHub, Inc.
  • 条款
  • 隐私