Javascript Node.js中setTimeout()回调中的'this'绑定

Javascript Node.js中setTimeout()回调中的'this'绑定,javascript,node.js,Javascript,Node.js,在Node.js中,在传递给setTimeout()的回调中,这个似乎绑定到setTimeout()本身返回的timeoutObject(在严格模式和非严格模式下!): 浏览器中的情况并非如此,在浏览器中,此被绑定到全局对象窗口(或者是未定义的,在严格模式下) 文档中没有提到这种非标准行为 为什么会这样?这里有一个讨论。这就解释了这个问题,甚至有人试图修复它,但没有被接受 以下是一些想法 setTimeout将计时器对象绑定到回调中的“this”对象。 首先,在大多数情况下,节点中的执行环境是一

在Node.js中,在传递给
setTimeout()
的回调中,
这个
似乎绑定到
setTimeout()本身返回的
timeoutObject
(在严格模式和非严格模式下!):

浏览器中的情况并非如此,在浏览器中,
被绑定到全局对象
窗口(或者是
未定义的
,在严格模式下)

文档中没有提到这种非标准行为

为什么会这样?

这里有一个讨论。这就解释了这个问题,甚至有人试图修复它,但没有被接受

以下是一些想法

setTimeout
将计时器对象绑定到回调中的“this”对象。 首先,在大多数情况下,节点中的执行环境是一个“模块”,因此

这就是浏览器和节点之间的区别。在浏览器中引用“窗口”对象很容易,因为它是一个全局对象。但在节点中,setTimeout/setInterval无法获取“导出”对象或模块的执行环境


无论如何,当前的set*()工作方式有一些优点(尽管它没有文档记录,但正在野外使用)。例如:

setInterval(function() {
  if (/* <condition> */)
    this.unref();
  // do more stuff
}, /* <n> */);
setInterval(函数(){
如果(/**/)
这是unref();
//多做事
}, /*  */);
Nodejs不是浏览器。你所说的“标准”是针对浏览器的。阅读文档:

要实现这两个计时功能,“this”应该绑定到窗口对象(在Nodejs中不可用)或工作对象(在Nodejs中不可用)

Nodejs有自己的全局对象,在这种情况下,这可能是一个很好的目标,但我认为最好将它绑定到这个函数,而不是一些全局对象。似乎来自Nodejs的开发人员也这么认为


这并不违反“标准”,因为标准与这样的环境无关,在这样的环境中,不存在窗口、导航和位置对象

这有什么不对?我指出了我认为不对的地方。我希望
这个
像在任何其他回调中一样绑定到全局对象。所有浏览器都将
绑定到全局对象,而Node.js不是.Hm,Node不是浏览器,不需要重复以前的错误。在node中使用全局对象是非常不受欢迎的,那么为什么要调用它的回调呢?相应的计时器(不是一个数字,但有自己的方法)更有意义。Node实际上不是一个浏览器,但它不是ECMAScript的另一个实现——它使用流行浏览器的JavaScript引擎。我认为答案是,由于ECMAScript规范中没有
setTimeout()
,Node.js有自己的实现,与所有浏览器中的实现方式不同。@kYuZz正是如此<代码>设置超时
由W3C/WHATWG定义,而不是ECMAScript。Node.js是ECMAScript的一个实现,但不是浏览器。本期中的讨论解释了这个问题,甚至有一个未被接受的版本。
var k=2;
exports.k=3;
console.log(k);//2
console.log(this.k);//3
setInterval(function() {
  if (/* <condition> */)
    this.unref();
  // do more stuff
}, /* <n> */);