什么`setTimeout`绑定这个`?
我试图创build一个例子,说明为什么成语var that = this
是必要的(例如这里所描述的)。
所以,我从一个错误的代码开始,将无法正确地绑定this
。 然而,我写的代码给了我一些意想不到的结果(从另一个方面):
message = "message in global scope"; // the below erroneous code aims to demonstrate why we need // the "var that = this" idiom to capture the "this" lexical scope var createLoggingFunctionWrongWay = function () { return function () { console.log(this.message); }; }; // the below *does* print "message in global scope" // ie fails in the way I expected createLoggingFunctionWrongWay.call({message:"message"})(); // I was expecting the below to also print "message in global scope" as // well, yet it prints "undefined" setTimeout(createLoggingFunctionWrongWay.call({ message: "message" }), 1000);
在nodejs
下运行时,我得到:
$ nodejs foo.js message in global scope undefined
我的问题是为什么第二个调用(使用setTimeout
)也没有以相同的方式失败,并解释this
指向Node.js
( message
variables所在的地方)的global
对象?
更新当我在匿名函数中插入一个console.log(this)
,在第一次调用时我得到了全局上下文对象(其中有message
所在),而在第二次调用时(通过setTimeout
),我得到以下对象:
{ _idleTimeout: 1000, _idlePrev: null, _idleNext: null, _idleStart: 1446483586705, _onTimeout: [Function], _repeat: false }
在Node.js中, setTimeout
的callback函数被作为上下文( this
)对象绑定的Timeout
对象调用,并且它们没有在其中定义的message
。 这就是为什么第二个方法打印undefined
。 你可以在这里看到相应的代码段。
var timer = new Timeout(after); var length = arguments.length; var ontimeout = callback; switch (length) { // fast cases case 0: case 1: case 2: break; case 3: ontimeout = callback.bind(timer, arguments[2]); break; case 4: ontimeout = callback.bind(timer, arguments[2], arguments[3]); break; case 5: ontimeout = callback.bind(timer, arguments[2], arguments[3], arguments[4]); break; // slow case default: var args = new Array(length - 2); for (var i = 2; i < length; i++) args[i - 2] = arguments[i]; ontimeout = callback.apply.bind(callback, timer, args);
您可以通过bind
方法将范围传播到返回的函数:
message = "message in global scope"; var createLoggingFunctionWrongWay = function () { return (function () { console.log(this.message); }).bind(this); }; setTimeout(createLoggingFunctionWrongWay.call({ message: "message" }), 1000);
否则,它在其范围内工作,实际上是通过忽视注入到最外层function的那个而导致全球性的。
一个简单的函数调用,没有注入的作用域(也就是说,你既没有使用call
,也没有apply
或bind
等等),全局上下文是默认的。 这主要是因为函数调用必须有一个上下文,但在这种情况下,没有特定的上下文绑定到该函数,所以它默认为全局的。
请注意,我们正在谈论的function不是原型的一部分。
- 你如何在node.js中共享EventEmitter?
- 当事件创buildOK时,Keen.io JS api响应{“code”:“UnknownError”}
- Express.js – foreach数据数组并将其存储在数据库中
- Node.js Q承诺,为什么使用defer()的时候可以使用this()?
- 使用Dropzone上传多个文件与节点multer时,LIMIT_UNEXPECTED_FILE问题
- “types错误:res.sendStatus不是一个函数”为什么我得到这个错误后有一段时间?
- APE和Node.js之间的主要区别是什么?
- React / Redux – 无法读取未定义的属性“XXX”
- 无法使用客户ID创buildBraintree客户端令牌