node.js: 无法读取未定义的 属性 'defaultEncoding'

node.js: Cannot read property 'defaultEncoding' of undefined

我想写一个可变的 write() 函数。

var write = function(s) {
    process.stdout.write(s);
}
write("Hello world!");

我以为你可以把它写得更短一点:

var write = process.stdout.write;
write("Hello world!");

但是在这里我会收到这个错误:

TypeError: Cannot read property 'defaultEncoding' of undefined
    at Writable.write (_stream_writable.js:172:21)
    at Socket.write (net.js:613:40)
    at repl:1:2
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)

这是为什么?

这一切都与 javascript 处理 this 的方式有关。在函数 process.stdout.write there is a calldefaultEncoding() 中使用 this 变量。

在 javascript 中,this 不会被赋值,直到对象调用定义 this 的函数并且它与调用对象相关。

因此在您的第一个示例中,this 指向 process.stdout 对象并且它具有方法 defaultEncoding。 在你的第二个例子中, thisundefined 因为函数是从全局命名空间调用的。当 process.stdout.write 尝试调用 defaultEncoding 时,它会抛出您提到的错误。

您可以使用 Function.prototype.call() 方法手动定义函数的 this 值。示例:

var write = process.stdout.write;
write.call(process.stdout, "Hello world!");

call的第一个参数是在函数内部用作this的对象。

我建议阅读 this article,它在 javascript 中解释了很多关于 this 的内容。

使用 .bind() 方法,它专为您的情况而设计。

var write = process.stdout.write.bind(process.stdout);
write("Hello world!");

这会将 process.stdout.write 方法中的 this 变量设置为 process.stdout