为什么我在node.js中得到这个奇怪的“无法在undefined中设置属性”

时间:2014-02-11 15:09:35

标签: javascript node.js

我有一个非常简单的nodeunit测试,完全是这样的:

'use strict';

var controllerUtils = require('../lib/controllerUtils');

function Mock() {
    this.req = { headers: {} };
    this.res = { };
    this.nextWasCalled = false;
    this.next = function() {
        this.nextWasCalled = true;
    };
}

module.exports = {
    'acceptJson': {
        'Verify proper headers were set': function(test) {
            var mock = new Mock();
            controllerUtils.acceptJson(mock.req, mock.res, mock.next);

            test.ok(mock.nextWasCalled);
            test.equal(mock.req.headers.accept, 'application/json');
            test.equal(mock.res.lean, true);
            test.done();
        }
    }
}

但是当我致电controllerUtils.acceptJson时,我收到错误TypeError: Cannot set property 'nextWasCalled' of undefined

所以我在chrome的控制台和节点命令行上测试了它,测试是:

function Mock() {
    this.req = { headers: {} };
    this.res = { };
    this.nextWasCalled = false;
    this.next = function() {
        this.nextWasCalled = true;
    };
}

var m = new Mock();
console.log(m.nextWasCalled); //logs false
m.next();
console.log(m.nextWasCalled); //logs true

我无法弄清楚为什么我的代码无法运行,因为这是一个非常简单的代码,它在chrome的控制台和节点命令行上都很好用。

PS:controllerUtils.acceptJson上的代码:

module.exports.acceptJson = function(req, res, next) {
    req.headers.accept = 'application/json';
    res.lean = true;

    next();
};

1 个答案:

答案 0 :(得分:3)

controllerUtils.acceptJson作为参数获取对函数的引用。它不知道它应该在哪个上下文中调用该函数,因此它在没有任何上下文的情况下调用它。

您的next方法要求上下文是定义它的对象。有两种方法可以修复您的代码:

将函数作为参数传递时将函数绑定到上下文:

controllerUtils.acceptJson(mock.req, mock.res, mock.next.bind(mock));

在定义函数时将函数绑定到上下文:

this.next = function() {
    this.nextWasCalled = true;
}.bind(this);