new fn 与 new fn() 的区别

解析 JavaScript 中 new 操作符带括号和不带括号的执行差异

问题

使用 new 创建实例时,new fnnew fn() 有什么区别?

解答

相同的情况

当构造函数不需要传参且直接访问实例时,两种写法结果一致:

function Parent() {
  this.num = 1;
}

console.log(new Parent());  // 输出:{num: 1}
console.log(new Parent);    // 输出:{num: 1}

不同的情况

当涉及成员访问或其他操作时,两种写法会产生不同结果:

function Parent() {
  this.num = 1;
}

console.log(new Parent().num);  // 输出:1
console.log(new Parent.num);    // 报错:undefined is not a constructor

原因分析

这是运算符优先级导致的:

new Parent.num 的执行顺序:

  1. 先执行 Parent.num,返回 undefined
  2. 再执行 new undefined,因此报错

new Parent().num 的执行顺序:

  1. 先执行 new Parent(),返回实例对象
  2. 再访问 .num 属性,返回 1

可以理解为:

  • new Parent.num 等价于 new (Parent.num)
  • new Parent().num 等价于 (new Parent()).num

关键点

  • new 后带括号的优先级高于不带括号
  • new fn() 会先创建实例,再进行后续操作
  • new fn.property 会先访问属性,再尝试 new 该属性值
  • 实际开发中建议始终使用 new fn() 的形式,避免歧义