改变函数的variables,并保持它的JavaScript?

我如何写这个,让lfmuser保持在UserModel.find()调用的函数中所做的更改? 如果我可以避免的话,我真的不需要将非常大的一段代码移动到每个块中。

 var np_handler = function (act) { var lfmuser = ''; if (act.params.length === 0) { UserModel.find({ nick: act.nick }, function (err, data) { if (!data) { lfmuser = act.nick; } else { lfmuser = data.lastfm; } }); } else { UserModel.find({ nick: act.params[0] }, function (err, data) { if (!data) { lfmuser = act.params[0]; } else { lfmuser = data.lastfm; } }); } }; 

在这种情况下,我只是将其余的代码(我使用lfmuser)移动到它自己的函数np(lfm, act){ }并在调用它时传递了正确的值。 asynchronous可以是一个痛苦:/

最简单的解决scheme是将其移动到np_handler函数之外。 请注意,随后对该函数的调用将会覆盖其值。

我创build了一个包装器对象,并将你的lfmuservariables列为对象的一个​​属性。 这不是全局的,它的值在你的函数完成执行之后会一直存在。

 var np_handler_object = { lfmuser = '', // variable in scope of the np_handler object and persists np_handler: function (act) { if (act.params.length === 0) { UserModel.find({ nick: act.nick }, function (err, data) { if (!data) { np_handler_object.lfmuser = act.nick; } else { np_handler_object.lfmuser = data.lastfm; } }); } else { UserModel.find({ nick: act.params[0] }, function (err, data) { if (!data) { np_handler_object.lfmuser = act.params[0]; } else { np_handler_object.lfmuser = data.lastfm; } }); } }; } 

你设置它的方式,variables的作用域是np_handler 。 这意味着每次调用这个函数时,都会得到一个新值(初始化为“')。

这听起来像是你想要的东西超越了这个function,所以在Javascript中这很容易 – 只有函数或全局范围。 所以删除var lfmuser = ''行应该做你想要的。

顺便说一句,当你在这里,一个局部variables和“?:”的使用缩短了代码,例如:

 var lfmuser = ''; ... var np_handler = function (act) { var nick = act.params.length ? act.params[0] : act.nick; UserModel.find({ nick: nick }, function (err, data) { lfmuser = data ? data.lastfm : nick; }); }; 

如果您不想使用全局variables,则可以像别人指出的那样,在其他地方将variables的范围。

有许多方法可以在函数调用中使variables持久化。 它们都涉及将variables声明或存储移动到函数范围之外,以便它不会被重新创build,然后在每次函数运行时死亡。

函数的属性

最简单的方法之一就是将其分配为np_handler()函数的属性。 这样可以防止任何全局命名空间的污染或冲突,但只要使用它的函数存在,就会使其持续存在。 这可以这样做:

 var np_handler = function (act) { if (act.params.length === 0) { UserModel.find({ nick: act.nick }, function (err, data) { if (!data) { np_handler.lfmuser = act.nick; } else { np_handler.lfmuser = data.lastfm; } }); } else { UserModel.find({ nick: act.params[0] }, function (err, data) { if (!data) { np_handler.lfmuser = act.params[0]; } else { np_handler.lfmuser = data.lastfm; } }); } }; // initialize np_handler.lfmuser = ''; 

全球范围

如果你想把它和函数放在同一个作用域中,你可以在同一个作用域声明它,而不是像这样在本地声明它,但是如果np_handler在全局作用域中,你现在在全局中有一个项目你通常尽量避免的范围:

 var lfmuser = ''; var np_handler = function (act) { if (act.params.length === 0) { UserModel.find({ nick: act.nick }, function (err, data) { if (!data) { lfmuser = act.nick; } else { lfmuser = data.lastfm; } }); } else { UserModel.find({ nick: act.params[0] }, function (err, data) { if (!data) { lfmuser = act.params[0]; } else { lfmuser = data.lastfm; } }); } }; 

全局命名空间对象

如果您需要它是全局访问的,但不想污染全局名称空间,或者想要避免名称冲突的可能性,则可以创build一个全局名称空间对象,并将全局variables设置为该物体的财产。 然后,您可以将所有全局variables作为属性放在一个主全局对象上,只在全局空间中引入一个新名称而不是多个。 你会这样做:

 // make sure myGlobals is defined and assign a property to it var myGlobals = myGlobals || {}; myGlobals.lfmuser = ''; var np_handler = function (act) { if (act.params.length === 0) { UserModel.find({ nick: act.nick }, function (err, data) { if (!data) { myGlobals.lfmuser = act.nick; } else { myGlobals.lfmuser = data.lastfm; } }); } else { UserModel.find({ nick: act.params[0] }, function (err, data) { if (!data) { myGlobals.lfmuser = act.params[0]; } else { myGlobals.lfmuser = data.lastfm; } }); } };