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

时间:2020-12-22 21:53:17

I have a very simple nodeunit test, exactly like this:

我有一个非常简单的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();
        }
    }
}

But when I call controllerUtils.acceptJson I get the error TypeError: Cannot set property 'nextWasCalled' of undefined.

但是当我调用controllerUtils.acceptJson时,我得到错误TypeError:无法设置未定义的属性'nextWasCalled'。

So I have tested it on chrome's console and on node command line, the test was:

所以我在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

I can't figure out why my code is not working since this is a very trivial code and it works great on both chrome's console and node command line.

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

PS.: Code on controllerUtils.acceptJson:

PS。:controllerUtils.acceptJson上的代码:

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

    next();
};

1 个解决方案

#1


3  

controllerUtils.acceptJson gets as parameter a reference to a function. It has no idea in which context it should call that function, so it calls it without any context.

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

Your next method requires that the context be the object in which it was defined. There are two ways to fix your code:

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

Bind the function to the context when you pass it as parameter:

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

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

Bind the function to the context when you define it:

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

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

#1


3  

controllerUtils.acceptJson gets as parameter a reference to a function. It has no idea in which context it should call that function, so it calls it without any context.

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

Your next method requires that the context be the object in which it was defined. There are two ways to fix your code:

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

Bind the function to the context when you pass it as parameter:

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

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

Bind the function to the context when you define it:

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

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