Nodejs/JavaScript模块加载和引用

Nodejs/JavaScript模块加载和引用,javascript,node.js,Javascript,Node.js,我最近开始学习JavaScript和NodeJS。我不知道为什么我会看到不同的结果。如果有人能解释导致输出变化的细微差别,我将不胜感激 var stream = require('stream'); var EventEmitter = require('events').EventEmitter; //typeof == function console.log(new stream().Stream() instanceof EventEmitter); // error console.

我最近开始学习JavaScript和NodeJS。我不知道为什么我会看到不同的结果。如果有人能解释导致输出变化的细微差别,我将不胜感激

var stream = require('stream');
var EventEmitter = require('events').EventEmitter; //typeof == function

console.log(new stream().Stream() instanceof EventEmitter); // error
console.log(new stream().Stream instanceof EventEmitter); // false
console.log(stream.Stream instanceof EventEmitter); // false...

console.log(new stream.Stream() instanceof EventEmitter); // true
console.log(new stream.Stream instanceof EventEmitter); // true

我会尽量保持简洁,很多事情都有答案,但这里有很多

var EventEmitter = require('events').EventEmitter; //typeof == function
EventEmitter通常与
new
一起使用。例如,
neweventemitter()
。在旧的javascript中,您可以执行
function Thing(){this.someprop=2;}
,然后执行
var a=new Thing()
,并能够访问
a.someprop
。在ecmascript 6+中,您可以使用
class
sugar。无论如何。您可以
new
up函数实现并获取函数的
this
。在您的情况下,这个“实例”还应该将
.constructor
属性设置为EventEmitter函数,如果您要重新设置它的话。它还将.prototype设置为EventEmitter.prototype

console.log(new stream().Stream() instanceof EventEmitter); // error
这是错误的,因为流不是新流()上的属性。并且流是
未定义的
。访问/调用未定义或null的属性将始终导致运行时错误

console.log(new stream().Stream instanceof EventEmitter); // false
您应该执行
new stream()instanceof events.EventEmitter
。同样,流是未定义的,不应该是任何东西的实例。请注意,
stream==stream.stream
;导出是流的快捷方式

console.log(stream.Stream instanceof EventEmitter); // false...
构造函数本身只是一个函数,函数不是EventEmitter

console.log(new stream.Stream() instanceof EventEmitter); // true
当您
new
a函数时,返回的“实例”有一个原型,它是函数的原型。这个原型又可以有一个原型,这就是原型继承在javascript中的工作原理。当您访问一个方法或属性时,jswalk会在原型链中寻找它。当您执行
instanceof
时,它只检查原型链的级别是否匹配。基本上,流在其原型链的某个地方有EventEmitter。它实际上只是stream.prototype之上的一个级别。repl中的proto将向您展示

console.log(new stream.Stream instanceof EventEmitter); // true

stream===stream.stream
,使用
new

时不必使用括号。嗨,很多事情都很有意义,现在都清楚了。Dint realize stream===stream.stream当我进行导入时,生成的流函数中有多个函数,如-Readable、Transform等。。。另一方面,这些函数本质上是静态的吗?取决于您所指的
static
(C/Java),但答案在它们的范围内是静态的。在文件的顶层,答案是肯定的,并且原型可以被认为是一个静态函数,因此,如果你调用new 10次,那么原型对于所有这些函数来说都是一样的。注意:如果函数被重新调用,函数中的变量总是被重新声明。不像C,是的,这里的流是一个循环引用。当我定义一个函数时,例如-var test=function(){function rr(){console.log(“rr”);}this.msg=“test”;},我无法访问其中的函数和变量,除非我启动它。我知道他们被监视了。所以,想知道“流”中的函数(如可读、转换等)如何在不启动“流”对象的情况下访问。例如-stream.Readable(返回一个函数)和test.rr(返回未定义的)。人们在stream.prototype上定义它们。因此,您不必执行
this.msg='test'
,而是执行
rr.prototype.msg='test'
。您在
rr
范围之外执行原型分配<代码>函数T(){};T.prototype.msg='test'。然后
newt()。非常感谢。试图理解JavaScript的细微差别。