require()和new require()之间有什么区别?

3
我的问题的核心是,什么是以下两个术语之间的区别:
var fs = new require('fs');

并且

var fs = require('fs');

如果我在任何地方都使用new,会有什么影响或注意事项吗?

在使用Webstorm时,我注意到只有当我使用new require('fs')时才能使智能感知工作。在开始为了更好的开发体验一致地使用它之前,我想了解更多信息。


3
@talles,我认为这并不完全是那个问题的重复:那个问题询问括号对require调用的影响如何影响new操作符;而这个问题询问new操作符如何影响require调用。具体地说,这个问题比较的是require()new require(),而我认为那个问题比较的是new (require())new require() - apsillers
是的,我已经看到了相关的问题,但它与我的问题非常不同,@apsillers 理解了我的意图。 - Mendhak
3个回答

8
首先:不要混淆 new require("...")(将require作为构造函数调用)和 new (require("..."))(将require调用的返回值作为构造函数来调用)。你正在使用第一种方法。 require 并不是以 new 的形式调用的。这不符合 Node 的惯例,而且通常很奇怪。你不应该这样做,因为它会降低代码的可读性。未来读者很可能会将其误认为是 new (require("..."))(即在由 require 返回的构造函数上调用 new),因为正常的 Node 风格不会在 require 上使用 new
现在,让我们谈谈实际的副作用。 new 会使一个函数运行其 [[Construct]] 内部方法,该方法执行以下操作:
  • 使用其原型设置为函数的 prototype 属性的新创建对象调用该函数,this 被设置为该对象

  • 返回一个结果:

    • 如果函数返回一个对象,则返回函数的返回值
    • 如果函数返回其他任何值,则返回新创建的 this 对象
new require 的返回值对于所有导出值为非原始值(这是几乎所有模块的情况;它们通常导出一个普通对象或函数,也是一种对象)的模块都是相同的。但在极少数情况下,如果你的模块确实导出了原始值,那么 new 将拒绝访问该值。 require(...)new require(...) 之间唯一可能的差异是 new 变体提供了一个不同的 this 值。然而,require 显然完全忽略了其 this 值。(请注意,Module.prototype.require -- 与普通的 require 不同的另一个函数 -- 在从一个模块中要求子模块时使用其 this 值,使用 module.require(...) 来实现。)

好的解释,附有具体链接。我也理解为什么你称之为奇怪,现在我不会再用 new require() 来污染我的代码了! - Mendhak

1
在Node.js中,“new”操作符用于创建新实例。正如您所知,在Node.js中,函数本身是一等对象。使用“new”运算符可以创建函数的新实例,并将其驻留在变量内部。
这是为了在程序中创建许多具有相同主体但不同名称的函数,以便它们具有不同的变量值。
另一方面,“require”用于导入您在其他地方创建的模块或现有的节点模块,就像您可能会在其他语言中导入库一样。在这种情况下,“require”将返回分配给变量的模块,该模块正在应用程序中导入。
当您在“require”中使用“new”时,它不做任何事情,只是导入您正在导入的模块的新实例。这种方法不是必需的,但它会起作用。
建议仅在要创建同一对象的多个实例和/或希望通过创建新对象的新实例来清除旧实例并将其放入同一变量中时使用“new”。

-1

思考一下。

require 返回 一些东西。

这与执行以下操作相同:

var foo = function(bar) {
    this.bar = bar;
};

var f = foo('bar');
console.log(f.bar); //ERROR
//vs:
var y = new foo('bar');
console.log(y.bar); // 'bar'

所以你的代码所做的就是使用require返回值调用new


5
除非我误解你的最后一句话(这可能是我自己的问题),否则这是不正确的。new(require('fs'))可以实现你所描述的功能(“用require返回的对象来调用new”)。而new require('fs')更接近于require.call(Object.create(require.prototype), 'fs') - apsillers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接