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);