gpt4 book ai didi

node.js - NodeJS Express app.locals 无法在函数中直接访问

转载 作者:太空宇宙 更新时间:2023-11-03 23:36:51 26 4
gpt4 key购买 nike

这是一个奇怪的问题,但请跟随我。我有一个带有express应用程序的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>

有趣的是,那一刻并没有引发异常。因此,正如文档所说,它是在 ejs 的范围内定义的。然而,ejs 引发了一个异常,表示该时刻未在 formatDate 定义。如果我将 formatDate 更改为以下内容,一切正常。

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

我的问题是在 ejs 中定义的函数如何确定作用域以及对它们应用哪些上下文。 ejs 是否对函数应用了与 float 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 之外; 该 block 内,moment 实际上是 locals.moment,因此您可以通过测试来查看它是否存在。

但是,当您可以 formatDate 时,它不会在 with block 的上下文中运行,因此 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();
}

解决此问题的一种方法是使用函数表达式:

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

(它还修复了您的测试,以查看 moment 是否实际定义)

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

关于node.js - NodeJS Express app.locals 无法在函数中直接访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31190603/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com