从模块内部调用 Node.js 模块函数

Calling a Node.js module function from within the module

我正在尝试编写一个节点模块以清理我的代码并将其分离到不同的文件中。

考虑以下代码:

module.exports = {
    Hello : function(request, reply) {
        return reply("Hello " + World());
    },
    World : function() {
        return "World";
    }
}

如果我导入上述模块并使用 Hello 函数作为特定路由的处理程序,我会收到 HTTP 500 内部服务器错误。

如果我将 Hello 函数更改为

,我已将问题缩小到对 World() 的调用
Hello : function(request, reply) {
    return reply("Hello World");
}

然后它工作正常,所以它似乎在从导出对象中调用另一个函数时被绊倒了

有谁知道为什么会这样以及如何解决?

您需要将 this 添加到 World() -

的调用中
module.exports = {
    Hello : function(request, reply) {
        return reply("Hello " + this.World());
    },
    World : function() {
        return "World";
    }
}

World是导出对象的属性,不是可访问范围内的变量——所以需要指定函数属于this.

你应该这样称呼它:

module.exports = {
    Hello: function(request, reply) {
        return reply("Hello " + module.exports.World());
    },
    World: function() {
        return "World";
    }
}

如果您的目标是更简洁的代码,我建议您将代码更改为:

function World() {
  return "World";
}
function Hello(request, reply) {
  return reply("Hello " + World());
}
module.exports = {
    Hello,
}

这将使您的代码更具可读性,并且您只会导出您实际需要的内容。此 question 对您的问题有其他解决方案。

好吧,让我们演示一下 this

this 没有定义函数所在的对象。它定义了调用函数的位置。所以同时;

var obj = {
    Hello : function(request, reply) {
        return reply("Hello " + this.World());
    },
    World : function() {
        return "World";
    }
};
obj.Hello("test", console.log);

会很好用;这不会;

var obj = { Hello : function(request, reply) {
                      return reply("Hello " + this.World());
                    },
            World : function() {
                      return "World";
                    }
          };

setTimeout(obj.Hello,100,"test",console.log);

这只是因为 obj.Hello 将在 setTimeOut 函数的定义中分配一个参数,并且该参数将被调用为 window 作为该函数的 this .所以你应该喜欢;

var obj = { Hello : function(request, reply) {
                      return reply("Hello " + this.World());
                    },
            World : function() {
                      return "World";
                    }
          };

setTimeout(obj.Hello.bind(obj),100,"test",console.log);
//or 
setTimeout(obj.Hello.bind(obj,"test",console.log),100);
//or
setTimeout((x,y) => obj.Hello(x,y),100,"test",console.log);