我正在尝试在node.js中创建一个模块/类来测量异步执行时间,但是不明白它有什么问题。我创建了以下类“Measure.js”
var Measure = module.exports = function(param_timeout, param_cb) {
this.timeout = param_timeout;
this.cb = param_cb;
}
Measure.prototype = {
startDate: "0",
timeout:"0",
cb:null,
start : function() {
this.startDate = new Date();
console.log('started');
},
stop : function() {
var stopDate = new Date();
this.cb(null,(stopDate-this.startDate));
}
}
我使用以下代码:
var Measure = require('./Measure.js');
measure1 = new Measure(100,function(err,result){console.log('result: ' + result)});
measure1.start();
//do something
measure1.stop();
它工作得很好。但是,如果我试试这个:
var Measure = require('./Measure.js');
measure1 = new Measure(100,function(err,result){console.log('result: ' + result)});
measure1.start();
//do something
setTimeout(measure1.stop,100);
它不起作用并抛出TypeError:
TypeError: Object #<Object> has no method 'cb'
我的代码出了什么问题?
答案 0 :(得分:6)
当您直接调用对象的方法时,this
在您的对象引用的方法中,但当您尝试将其用作参数时,this
将引用全局对象(global
或window
)。
在你的情况下更好地替换
setTimeout(measure1.stop,100);
带
setTimeout(function() { measure1.stop(); }, 100);
有关this
行为的更多信息:http://bonsaiden.github.com/JavaScript-Garden/#function.this
答案 1 :(得分:3)
可怕的timeout-switch-context错误再次发生!你看到了你看到的内容,因为setTimeout调用的函数中的this
对象不是measure1
- 它是global
(= window
,当在浏览器中执行此脚本时)。引用the MDN:
setTimeout()
执行的代码在单独的执行上下文中运行 到它被调用的函数。因此,this
被调用函数的关键字将设置为window
(或global
) 对象,它与函数的this
值不同 这叫做setTimeout
。
顺便说一句,这很容易检查:
stop: function() {
var stopDate = new Date();
if (! this.cb) {
console.log(this);
} // *Window*/_display...
}
......并修复:
setTimeout(function() {
measure1.stop();
}, 100);