Node.js类模块系统

我试图在node.js中创build一个模块/类来测量asynchronous执行时间,但不明白它有什么问题。 我创build了以下类“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' 

我的代码有什么问题?

当你直接调用对象的方法时, this里面的方法引用了你的对象,但是当你试图用它作为参数的时候, this会引用全局对象( global或者window )。

在你的情况下更好地更换

 setTimeout(measure1.stop,100); 

 setTimeout(function() { measure1.stop(); }, 100); 

更多关于this行为: http : //bonsaiden.github.com/JavaScript-Garden/#function.this

可怕的超时切换上下文错误再次发生! 你看到你所看到的,因为setTimeout调用的函数中的this对象不是measure1 – 它是global (= window ,当这个脚本在浏览器中执行时)。 引用MDN :

setTimeout()执行的代码在一个单独的执行上下文中运行,从它被调用的函数。 因此,被调用函数的this关键字将被设置为window (或global )对象,它不会与调用setTimeout的函数的this值相同。

顺便说一下,检查很容易:

 stop: function() { var stopDate = new Date(); if (! this.cb) { console.log(this); } // *Window*/_display... } 

…并修复:

 setTimeout(function() { measure1.stop(); }, 100);