NodeJS Express app.locals不能直接在函数中访问

这是一个奇怪的问题,但跟着我。 我有一个具有快速应用程序的nodejs服务器。 在应用程序中,我设置我的本地人如下:

var moment = require('moment'); app.locals.moment = moment; 

ejs被呈现为:

 exports.page = function (req, res) { res.render('first-page'); }; 

然后,在我的ejs中,我有以下代码:

 <% if (!moment) { throw new Error('moment is not defined'); } function formatDate(date) { return moment(date).format(); } %> <p><%= formatDate(1435856054045); %></p> 

发生的有趣之处在于那一刻不会引发exception。 因此,正如文献所说,它在ejs的范围内定义。 然而,ejs说在formatDate没有定义时刻的exception。 如果我将formatDate更改为以下,一切正常。

 function formatDate(date) { return locals.moment(date).format(); } 

我的问题是ejs中定义的函数是如何确定的,以及哪些上下文适用于它们。 ejs是否将一个不同的上下文应用于浮动JavaScript? 我假设它做了一些像formatDateFunctionPointer.call(ejsScope, ...);

ejs输出生成的函数(模板被编译到这个函数)时,问题就变得清晰了:

 with (locals || {}) { if (!moment) { throw new Error('moment is not defined'); } function formatDate(date) { return moment(date).format(); } ... } 

问题在于你的formatDate函数被挂到了with block之外; 那个块里面moment其实locals.moment ,所以你的testing看看它是否存在着作品。

然而,当你可以formatDate ,它不会在with块的上下文中运行,因此, moment不存在(但是locals.moment的确如你已经发现的那样)。

以下是这个问题的一个独立的例子:

 var obj = { test : 123 }; with (obj) { if (test !== 123) throw new Error('test does not equal 123'); function showTest() { console.log('test', test); } showTest(); } 

解决这个问题的一种方法是使用函数expression式:

 <% if (typeof moment === 'undefined') { throw new Error('moment is not defined'); } var formatDate = function(date) { return moment(date).format(); }; %> <p><%= formatDate(1435856054045); %></p> 

(它也修复你的testing,看看是否实际定义的moment

或者您可以将EJS _with选项设置为false