Javascript 在窗口对象上设置属性是否被认为是错误的做法?

Javascript 在窗口对象上设置属性是否被认为是错误的做法?,javascript,architecture,Javascript,Architecture,我正在编写一个非常复杂的JavaScript应用程序,它有一个MVC架构,我正在使用Prototype的支持和模块模式来实现它。该应用程序使用AJAX和Observer模式。我在加载DOM后创建控制器实例,向它传递一个视图和一些从JSON数据创建的模型,然后它就消失了 然而,我发现我必须将我的控制器实例设置为窗口对象上的一个属性,即不使用var声明它,因为我有一个AJAX成功回调,它刷新了控制器拥有的视图对象,在代码中,我可爱的小MVC世界不在范围内 我研究了将视图对象作为参数传递给包含AJAX

我正在编写一个非常复杂的JavaScript应用程序,它有一个MVC架构,我正在使用Prototype的支持和模块模式来实现它。该应用程序使用AJAX和Observer模式。我在加载DOM后创建控制器实例,向它传递一个视图和一些从JSON数据创建的模型,然后它就消失了

然而,我发现我必须将我的控制器实例设置为
窗口
对象上的一个属性,即不使用
var
声明它,因为我有一个AJAX成功回调,它刷新了控制器拥有的视图对象,在代码中,我可爱的小MVC世界不在范围内

我研究了将视图对象作为参数传递给包含AJAX代码的函数,但这会变得非常混乱,并导致一些严重违反MVC模式的行为,例如耦合模型和视图。太可怕了


将控制器实例直接存储在
窗口
上这样的操作是否被认为是不好的形式?对我来说,这有点像使用全局变量,但我看不到任何解决方法。

在窗口对象上设置属性等同于创建全局变量。也就是说,有时这样做是不可避免的,但您应该尽量将其保持在最低限度,因为它最终会污染全局名称空间

在您的情况下,创建单个属性并不是那么糟糕。如果您想格外小心,可以显式地为需要全局访问的任何内容创建名称空间:

// In init:
var mynamespace = {};

. . .

// Once the controller is available:
var namespace = window.mynamespace;
namespace.controller = controller;
namespace.foo = bar; // Set other stuff here as well.

我会说这是个坏习惯。如果必须的话,您可以始终轻松地为应用程序创建一个名称空间,并将全局变量放在其中。

当您想调用一个名称事先未知的全局函数时,它们非常有用

var funcName = "updateAns" + ansNum;
window[funcName]();
它们可以用来 a) 在大多数情况下避免邪恶的评估。 b) 避免对全局变量的引用错误

x=x+1
如果未定义全局x,将生成参考错误。
window.x=window.x+1
不会

你能发布一个小的代码示例吗?恐怕不行。我在家,代码在工作,更重要的是,我想我必须发布大量代码来说明这一点——我不喜欢阅读“文本墙”问题,所以我不想把它强加给别人!为什么MVC会超出范围?您的AJAX回调是否至少应该在闭包中捕获对它的引用?我对闭包不太精通。从本质上讲,AJAX函数位于控制器中,它由一个模型函数调用,该模型函数本身由另一个模型实例的更新调用(因此是Observer模式)。我正在使用Prototype的
onSuccess
回调,而
这个
在这一点上指的是
窗口
。然后简单地将
var=this
放在回调代码的前面,然后将回调中的所有引用更改为
this
。或者,使用Prototype的来修复
的值,谢谢。出于某种原因,我没有想到使用名称空间,尽管我在其他地方使用了名称空间。